Is there a reasonable way of having links external to the OpenLayers map DOM element invoke popups properly on the map? For example, I have a list of properties in a sidebar that I would like to be able to click on to open their respective popups in the map (not unlike Google Maps does with business listing pages). For the life of me, I cannot find a way to do it without tons of convoluted JavaScript code.
So far I have been trying to locate the feature that corresponds to a given property by pulling the nid from attributes I have set on both the property's DIV tag and the feature attribute via jQuery, then binding a click handler to the property listing. However, all attempts to get a valid coordinate from the feature to invoke OpenLayers.Map.triggerEvent() with have been fruitless so far (.lonlat is null, .geometry is in coords that I can only assume are transformed by a projection). jQuery code snippet that is failing is below:
// On submarket map view page, add click handler to anchor links to the sidebar property lists:
$('dl.submarket-props dd a').click(function() {
var $this = $(this);
// Get our OpenLayers.Map object:
var $map_obj = $('.node-submarket .openlayers-preset-ol_properties');
var ol_map = $map_obj.data('openlayers').openlayers;
// Pull nid from attribute set in TPL file:
var nid = $this.parent().attr('nid');
// Find our layer using another attribute set in the TPL file:
var layer_id = $this.parent().attr('layer');
var ol_layers = ol_map.getLayersByName(layer_id);
// Make sure we don't get an empty array back:
if (ol_layers && ol_layers.length) {
// Pull features from layer:
var features = ol_layers[0].features;
// Since OpenLayers.Layer.Vector.getFeaturesByAttribute appears to not be implemented (although documented):
if (features && features.length) {
for (var idx in features) {
feature = features[idx];
if (nid == feature.attributes['nid']) {
// Yay! We've found our target feature. Now try to pull some valid coords to use for the event object:
var evtPx = {xy: ol_map.getPixelFromLonLat(feature.lonlat)};
// Invoke click event on map, which should in turn invoke the proper event handlers for the feature's popup:
evtPx.type = 'click';
ol_map.events.triggerEvent('click', evtPx);
}
}
} // if (features && features.length)
else {
alert('no features');
}
} // if (ol_layers && ol_layers.length)
else {
alert('no layers');
}
});
Am I going about this all wrong? I'm working with the OpenLayers 2.9 library that the 6.x-2.0-alpha10 module was pre-configured for on D6.19.
Comments
Comment #1
arpieb commentedNevermind... I dug more into the OpenLayers.Popup class, and found a function that worked perfectly (called in the context of the Drupal OL module's JS framework):
I had mistaken this as an internal handler, and didn't realize you could call it directly with no ill effects.
Comment #3
joeysantiago commentedHello,
i'm trying to do the same thing... but i'm having no luck. How do you get the feature object to pass to the function Drupal.openlayers.popup.popupSelect.clickFeature ?
thanks
Comment #4
zzolo commentedHi @joeysantiago, take a look at the Popup behavior Javascript; it should help you. I think this is in includes/behaviors.
Comment #5
joeysantiago commentedHello... thanks, i already looked into it, but haven't found any way to do this... i tried to look for the object feature to pass to the function, but had no fortune.
can you give me a snippet? thanks
Comment #6
devtherock commentedLooking for same thing, anybody got solution ?
thanks
Comment #7
devtherock commentedFound a new way of doing it. Actually I was looking for something like.
---------------------- ----------------------------
---------------------- ----------------------------
-Node List here- -----Map here----------
--------------------- ----------------------------
--------------------- ----------------------------
--------------------- ----------------------------
[both are views left one is attachment with openlayer map view.]
So now if user click on any node title listed on left, it should show a respective popup on map. What I have done I am going to share.
Added following js code in my custom js fil
Now you can add a link like:
<a href="#" onclick="show_popup(nid)">Example</a>or you can use Jquery to run this event.Hope this will work for everyone.
Thanks
Kuldev
Comment #8
core44 commentedDesperately trying to get this to work with no success. Is it essential that the list of nodes is an attachment view. When I create an attachment view I'm not given the option to attach it to my openlayers display... only to the default display? I have tried with a seperate block but on click I get no popup.
Comment #9
devtherock commentedI hope you took all steps described here : http://drupal.org/node/627816
no not at all attachment isn't mandatory, actually what you need is one view ( create one openlayer and listing block) having same filter and sorting.
could you check in firefox's error console what it is saying.
if error is something like : feature is undefined
then probably you need to add nid field in your openlayer view.
try this
hope this work
thanks
Comment #10
shiraz dindardevtherock,
thank you so much for this. i got it to work without much hassle. i simply put the js next to a custom module, and in the custom module i have a map_alter hook. i load the js with drupal_add_js within that hook.
i had to change layers[1] to layers[2] because i have 3 layers on the page.
and that was it!
thanks again!
shiraz
Comment #11
Devcal commentedThanks,
it works , but I have a problem with feature.attributes.description !
when I click on the marker, the popup appears well (title, description, image), but when i click on the new link, description is empty !
Any idea ?
Comment #12
jeffschulerMarked #938558: Open marker popup from link? as duplicate.
Comment #13
Barto.G commentedThanks,
This solution works perfectly for the popup but when you are on a layer which only has tooltip you get an error due to the following line: Drupal.openlayers.popup.popupSelect.clickFeature(feature);
Would anyone now how to trigger the tooltip instead of the popup ?
Cheers
Guillaume
Comment #14
Admdebian commentedI have D7 and dev OL. I've tried your code but I get: "undefined method" at this line:
Drupal.settings.getAllFeature = $('div#openlayers-map-auto-id-0').data('openlayers').openlayers.layers[1];
I read about changes in ne OL versions, but I can't make things work.
Comment #15
vlad.dancerU can use Drupal.openlayers.popup.popupSelect.clickFeature(Drupal.openlayers.popup.popupSelect.layers[0].features[0]);
Drupal.openlayers.popup.popupSelect.clickoutFeature(Drupal.openlayers.popup.popupSelect.layers[0].features[0]);
Comment #16
tommeir commentedHere is what i wrote based on a rewrite of #7
It works for any amount of layers (each organic group we have can use different layers combo).
Its also more memory friendly and stuff...
Comment #17
hypertext200Here is the markup for views attachment unordered list:
Comment #18
SophieG commentedCould you please explain a little more, i can't make it work !!
thanks
Comment #19
ghalenir commentedRegarding to #17
When you click on the link it says
Uncaught TypeError: Cannot read property 'layer' of undefined
Comment #20
Rob C commentedcurrent_feature.attributes.nid has to be available, so the trick is to abuse the ol title field to set the nid (and hide it on the display) and render the title/body/other fields in a custom field and add that as the ol body field.
This way you can use the nid for the features array and pick the correct feature, else you'll get an error like ^^.
This also works with ajax! So you can create some amazing stuff already.
Comment #21
pmusaraj commentedI did get #17 to work by creating the object before the loop. Like so:
And for my purposes, I did not need the map to zoom in to the location, so I did the second part of the script like this:
Comment #22
sansui commentedThis worked pretty well following instructions in #17 and paying attention to the right classes. A click centers the map on the appropriate marker, but for whatever reason I cannot get the popup to open.
Any live examples of this working out there?
Edit: nevermind - I forgot to update an instance of nid to pid for my use. Popups now functioning just fine
Comment #23
tko commentedCan't get #17 to work no matter what I do.
Using latest -dev release.
What should my .container class be? Must I define a MODULENAME?
Can someone please elaborate?
Comment #24
jpablusco commentedI am not an expert but this is the way it worked for me:
Sorry for my non technical description
Comment #25
Levin commentedThe solutions listed in above works well with the case when a node has only one location. To support the case when a node has multiple locations, below is what I did:
1. In the backend
In my case, I am using views to display the map data. Address field and geofield are used to represent the location and cooridinates separatly. A node has multiple locations/coordinates. in the node, one location correspods to one cooridinate.
1) Add the Address field and geofield to the Fields. in the "MULTIPLE FIELD SETTINGS" field setting, uncheck the "Display all values in the same row".
2) Add the Address field delta and geofield delta to the Fields
3) With the patch provided in the lastest Dev version views (https://drupal.org/node/699252), Add one more Filter, fields comparison, select the two delta fields to be equal.
4) Add the external anchor Markup which triggers the popup when clicked.
<a herf="#" class= "olmapmarkerclass" data-nid="[pid][field_teacher_coordinates]" data-geoida = "pid" data-geoidb = "field_teacher_coordinates"> show marker</a>in above markup, the pid is the node id, and the field_teacher_coordinates is the coordinate field.
2. In the frontend
in the frontend. js codes would build up the map object when the anchor link is clicked the first time. while building up the map object, the node id and cooridinate are combined to generat an unique key to identify the features in the map. By map object, it means the Drupal.settings.nid object used below.
Comment #26
jamsilver commentedOK - I had to extend it a little bit further to be able to handle situations where there are multiple maps on the page (like in different horizontal tabs). Turns out in this situation
Drupal.openlayers.popup.popupSelect.clickFeature(feature)simply will not do the trick, since Drupal.openlayers.popup.popupSelect is a helper put in place by openlayers_behavior_popup.js to point to the control it added to the map for selecting markers and only points to the latest-map-rendered, rather than supporting multiple maps.I've put together the ideas in previous code examples above and come up with the following solution:
1. Make sure you are rendering the 'nid' field for each result in the Openlayers Data views display - that makes it available as an attribute on each marker
2. Use an anchor tag like the following:
3. And then the following code pieces it all together:
Hope someone finds this helpful!
Perhaps it would be a nice idea to get something like this into openlayers so it's easier to get node-id-based-show-marker links onto the page?
Comment #27
jpablusco commentedIt does not work when the marker is inside a cluster (using the Cluster Features)
Is there a way to make it work? Thanks
Comment #28
perpignan commentedIt's work with openlayer 7.x-2.0-beta 9 but since the update on beta 11, i have some problem with : No popup open when anchor tags are clicked.
I hope it will be corrected on next version !
Comment #29
milos.kroulik commentedAre there any errors in your browser console? They might be helpful for debugging this issue.
Comment #30
basvredelingCleaning up the issue queue for #2670484: Stable 7.x-2.0 release.
Please supply a patch for review if status "needs review" is applied.
If this is a bug, it should be a new issue.
Feel free to open a bug report for the issue mentioned in #28
The original post was a support request which has been answered extensively.
Re-closing.
Comment #31
fonant commentedI wonder if someone can help: How do I get the NID values from the "openlayers data overlay" data array into the features on the map?
My OpenLayers Data Overlay has the NID values, but they don't appear in the feature.attributes array.
Perhaps this is something that has changed since 3 years ago...?
Comment #32
basvredelingHi @fonant, let's not reopen this support request. This issue started as a D6 support request and any suggested solution might indeed have changed or no longer work.
I believe you are referring to #26. You probably have to create a field containing the mentioned anchor tag. Then, change the display format settings to vector data overlay. And configure the title of the feature to display the field you just created.
If you want more advanced external triggers for your features you can also try this module as an example: https://www.drupal.org/project/olfp (it's currently unsupported).