Google Maps and ASP .NET MVC - Center the map at a marker - asp.net-mvc

I'm building a page with a Google MAP that has a side bar with dynamically created divs linked to positions of markers in the map.
I'm using ASP.NET MVC with JQuery and Google Maps API v3.
Here is a look of it.
This page is loaded in a splash window and is generated dynamically.
In the background page the user types a state or city in an input field and in my controller action I search for all people that are located in that area and return a JSON.
I get the JSON and populate the map with markers and then I make the list of divs in the side bar.
I'd like to add a function to those divs that when they are clicked the map will center at the marker.
I came up with an idea for this solution which I could not finish.
I added class="clickable" and the attributes "Lat" and "Lng" with the values equal to the ones in the markers they are related to, and I tried to get their click event with JQuery and then set the map center with its Lat and Lng like this:
$(".clickable div").click(function(){
$('map_canvas').panTo($(this).attr('lat'), $(this).attr('lng'));
}
I had 2 problems with this approach.
- First, I didn't know how to get the map with JQuery.
I found 2 ways using like $('map_canvas').gMap but it didn't work. Tried a couple more things that I've found here in Stackoverflow but also didn't work.
Second - The JQuery would not catch the event click from the DIVs.
I tested on Google Chrome console the JQuery code and It worked but then my code would not trigger the click.
I tried something like $(".clickable div").click(function(){ alert("test"); } on Google Chrome and it worked, but in my script it did not.
I also tried to add listeners using addDomListener in my code but couldn't get around that either.
Could anyone please give me a light what would be a good way to do this without having to recreate the map when a div is clicked.
I also don't like the idea of adding Lat and Lng attributes to the divs, I don't know if that would work in any browser or if its good practice. I'm just out of solutions to this.
Here is the code I'm using. (I removed some of it to make it shorter and easier to read)
$(document).ready(function () {
//Google Maps API V3 - Prepares the ajaxForm options.
var options = {
beforeSubmit: showRequestPesquisaAdvogados,
success: showResponsePesquisaAdvogados,
type: 'post',
resetForm: false
};
$('#form-pesquisaAdvogado').ajaxForm(options);
//$(".clickable").click(function () { alert($(this).attr('lat')) });
});
function showRequestPesquisaAdvogados(formData, jqForm, options) {
$("#modal-processing-background").show(); //Shows processing splash window
}
function showResponsePesquisaAdvogados(responseText, statusText, xhr, $form) {
$("#modal-processing-background").hide();
//Hide processing window
loadSplashWindow();
CreateMap(responseText);
CreateSideBar(responseText);
}
}
function CreateMap(json) {
var mapOptions = {
center: new google.maps.LatLng(json[0].Endereco.Lat, json[0].Endereco.Lng),
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP
// marker:true
};
var infoWindow = new google.maps.InfoWindow();
var map = new google.maps.Map(document.getElementById("map-result"), mapOptions);
for (i = 0; i < json.length; i++) {
var data = json[i]
var myLatlng = new google.maps.LatLng(data.Endereco.Lat, data.Endereco.Lng);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: data.Endereco.Logradouro
});
(function (marker, data) {
// Attaching a click event to the current marker
google.maps.event.addListener(marker, "click", function (e) {
// Prepare the infoWindows content.
var contentString = //my content;
infoWindow.setContent(contentString);
infoWindow.open(map, marker);
});
//here I tried to add the listener to the div.
google.maps.event.addDomListener($(".clickable")[i], 'click',
function () {
map.panTo(new google.maps.LatLng($(this).attr('lat'),
$(this).attr('lng')));
});
})(marker, data);
}
}
function CreateSideBar(json) {
$(".sideBarConteiner").empty();
for (i = 0; i < json.length; i++) {
var contentString =
"<div class='clickable' lat='" + data.Endereco.Lat +
"' lng='" + data.Endereco.Lng + "' >" +
//...div's content here
"</div>";
$(".sideBarConteiner").append(contentString);
}
}
If you have any suggestions to make the code better or better practices, since I have only 3 months of experience with programming I might be going in the wrong direction without knowing, so please, feel free to change something if you think it'd be a better way.
I know my post is a bit lenghty, I just wanted to make it clear.
Thank you for your support in advance.
Regards,
Cesar.

I've found a way to do this by creating a global variable in javascript and keeping the map information in order to call it again later.
To to this I just added a var "map" right at the top of the .
<script type="text/javascript">
$.ajaxSetup({ cache: false }); //Forces IE to renew the cash for ajax.
var zoom = 8;
var mapOptions, map;
And then call a method to pan to the right point.
I added the properties Lat and Lng to the div and then pass the div in the javascript function and get the attributes from it.
function CreateSideBar(json) {
$(".sideBarConteiner").empty();
for (i = 0; i < json.length; i++) {
var contentString =
"<div class='clickable' data-lat='" + data.Endereco.Lat +
"' data-lng='" + data.Endereco.Lng + "' onclick='MarkerFocus(this)'>" +
//...div's content here
"</div>";
$(".sideBarConteiner").append(contentString);
}
}
And in my function:
function MarkerFocus(obj) {
var myLatlng =
new google.maps.LatLng($(obj).attr('data-lat'), $(obj).attr('data-lng'));
map.panTo(myLatlng);
}
It worked for me. I hope it helps you too.
Thanks to all for the help and support.
Cesar

Related

A-Frame + AR.js: How to add objects dynamically in Arjs when tapping on screen?

I'm currently working on an A-Frame AR app by using ar.js (I have to use ar.js). The goal is to dynamically add objects to the scene when tapping on the scene. Unfortunately nothing seems to work out. I managed to change the colors of an existing object when tapping on the screen but not adding a new one. Could someone please help me out here? I would be really grateful!
AFRAME.registerComponent('cursor-listener', {
init: function () {
var currentEl = this.el;
currentEl.addEventListener("click", function (evt) {
console.log("I was clicked!");
currentEl.setAttribute('material', {"color": "blue"});
var el = document.createElement("a-entity");
el.setAttribute('geometry', { "primitive": "sphere", "radius": "1" });
el.setAttribute('position', this.el.object3D.position)
const randomYRotation = Math.random() * 360
el.setAttribute('rotation', `0 ${randomYRotation} 0`)
el.setAttribute('visible', 'true')
el.setAttribute('shadow', {receive: false})
this.el.sceneEl.appendChild(el);
});
},
});
this.el.sceneEl.appendChild(el);
You should append the element to the marker node, and treat it as your "root" element - as it's the one being tracked when detected by camera:
<script>
AFRAME.registerComponent('cursor-listener', {
init:function () {
const marker = document.querySelector("a-marker")
var el = document.createElement("a-sphere");
marker.appendChild(el);
}
})
</script>
<!-- scene and stuff -->
<a-marker preset="hiro>
</a-marker>

Openlayers 3 popover putting each word on one line

Working on an OL3 map, and am getting stuck on popover style. I haven't added any CSS to change it at all and it is currently being handled by default Bootstrap settings.
Okay so the problem: each word is being displayed on it's own line. How can I change this? Or, a better question, how do I control the style of the popovers?
This is was it looks like now: http://i.imgur.com/lrLYbag.png
The code handling popups:
//popups
var element = document.getElementById('popup');
var popup = new ol.Overlay({
element: element,
positioning: 'bottom-center',
stopEvent: false
});
map.addOverlay(popup);
// display popup on hover
map.on('pointermove', function(evt) {
var feature = map.forEachFeatureAtPixel(evt.pixel,
function(feature, layer) {
return feature;
});
if (feature) {
var geometry = feature.getGeometry();
var coord = geometry.getCoordinates();
popup.setPosition(coord);
$(element).popover({
'placement': 'top',
'html': true,
'content': feature.get('name')
});
$(element).popover('show');
} else {
$(element).popover('destroy');
}
});
Thanks!
I think you just need to add some css to the #popup element you're using for the popup.
Something like:
#popup {
min-width: 280px;
}
Take a look at this example http://openlayers.org/en/master/examples/popup.html for styling ideas.

Loading Fusion Tables InfoWindow data in a div outside map

I hope someone can help with what is probably a fairly simple query. I have seen a question on here about trying to do this without a mouseclick, but I want to add an event listener to the markers on the Fusion Table map that will load the infoWindow content in a separate div below the map. So far I have suppressed the infoWindow, but I'm a bit lost on the next step of adding the click, retrieving the data relevant to that marker and loading into the div.
The marker display is limited to markers within a set radius of the user's location, in order to reduce load time.
I'm assuming I need to start with something like this:
google.maps.event.addListener(layer, 'click', function() {
I'd be grateful for any clues.
Here's the relevant bit of my code so far:
var tableid = '[ID]';
var layer = new google.maps.FusionTablesLayer({
query: {
select: 'Location',
from: tableid,
where: 'ST_INTERSECTS(Location, CIRCLE(LATLNG'+marker.position+', 2000))'
},
options: {
suppressInfoWindows: true
}
});
var circle = new google.maps.Circle({
map: map,
radius: 2000,
fillOpacity: 0.1,
strokeOpacity: 0,
clickable: false
});
circle.bindTo('center', marker, 'position');
layer.setMap(map);
});
EDIT:
For everyone's amusement, this is what I've tried so far:
google.maps.event.addListener(layer, "click", function () {
$('#infoWindowDiv').append('new google.maps.infoWindowHtml');
});
It probably comes as a surprise ot no-one that it doesn't work. But hey, at least I'm trying! Thanks
EDIT 2:
I'm delighted to say I have found a solution that works - which I post here for anyone else who might have the same problem/goal:
google.maps.event.addListener(layer, "click", function (e) {
document.getElementById("infoWindowDiv").innerHTML = e.infoWindowHtml;
});
I'm delighted to say I have found a solution that works - which I post here for anyone else who might have the same problem/goal:
google.maps.event.addListener(layer, "click", function (e) {
document.getElementById("infoWindowDiv").innerHTML = e.infoWindowHtml;
});

Why is my Google Map in a jQuery UI tab only displaying one tile at the top left corner of the screen?

I have two Google Map API v3 Maps in jQuery tabs. They both display the first time they appear in their tabs, but the initially deselected tab only displays a tile or so at the top left-hand corner.
Calling google.maps.event.trigger(all_map, 'resize') periodically does not change this.
In my code I have:
<div id='all_map_canvas'>
</div>
<script>
function show_all_map()
{
var center = new google.maps.LatLng(%(center_latitude)s - .15, %(center_longitude)s + .2);
var myoptions = {
zoom: %(zoom)s,
center: center,
mapTypeId: google.maps.MapTypeId.TERRAIN
};
all_map = new google.maps.Map(document.getElementById('all_map_canvas'), myoptions);
all_map.setZoom(%(zoom)s);
jQuery('#all_map_canvas').show();
google.maps.event.trigger(all_map, 'resize');
}
function show_all_map_markers()
{
%(all_map_markers)s
}
var markers = [];
jQuery('#all_map_canvas').width(jQuery(window).width() - 300);
jQuery('#all_map_canvas').height(jQuery(window).height() - 125);
How can I make both maps display in full after tab swaps?
I had the same problem: Google map in div that has style display:none;.
Solved it with this two steps:
Removing all additional styling of the div I'm placing the map except height:100%;
Initiate the map after the holding div is displayed not when the it is created. In my case in the callback function of the show method:
CSS
.main-window #map{
height:100%;
}
JS
$('.main-window').show(3000, function() {
// create the map after the div is displayed
var mapOptions = {
center: new google.maps.LatLng(42.499591, 27.474961),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map"), mapOptions);
});
HTML
<div class="main-window">
<div id="map"></div>
</div>
Initiating it in events like jQuery's '$(document).ready(...' or Google's 'google.maps.event.addDomListener(window, "load", ...' is not working for some reason.
Hope it helps.
I am using gmaps.js which is a simplified api for google map. But it's simply a matter of attaching a tabsshow event in javascript and refreshing the map in the delegate's function.
Here's the code I use for gmaps.js
$('#tabs').bind('tabsshow', function(event, ui) {
event.preventDefault();
if (ui.panel.id == "tabs2") {
//gmaps.js method
map.refresh();
map.setCenter(lastLoc.lat(), lastLoc.lng());
//for native google.maps api
google.maps.event.trigger(map, 'resize');
map.panTo(new google.maps.LatLng(lastLoc.lat(), lastLoc.lng()));
}
});

iScroll scrollToElement not working with jQuery Mobile

I have something similar to this iScroll example: http://cubiq.org/dropbox/iscroll4/examples/simple/
Except that I'm using jQuery mobile (i.e., the header, footer, and content are set using jQuery Mobile). Everything is running smoothly except for scrollToElement.
Is there any way to get scrollToElement working when using jQuery Mobile and iScroll?
Here's the iScroll script I currently have:
var myScroll;
function loaded() {
myScroll = new iScroll('wrapper');
}
document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
document.addEventListener('DOMContentLoaded', function () { setTimeout(loaded, 200);}, false);
EDIT: Forgot to mention what I'm trying to achieve. In the iScroll example mentioned above, I'm trying to scroll to a specific row. The only problem is that jQuery Mobile prevents scrollToElement from working for some reason.
Also make sure that you're using a timeout
setTimeout(function () {
myScroll.scrollToElement(".elementClass", "0s");
myScroll.refresh();
}, 0);
The workaround I have found is to capture the elements position and then use scrollToPage():
var w = $("#showselectedauthors").offset().top;
// ...
$.storeScroller.scrollToPage(0, w);
Of course for this to work you have to capture the position when the element is visible or the offset will be meaningless. You can do this when the page is built but before the scroller is initialized.
In my case the element is visible and I capture w at that time. I then refresh some content and refresh the scroller. After I do that I want to make sure the element is still visible.
Case anyone needs to scroll to a jQuery Object here's my code .
Make sure you're calling this method inside a setTimeout and your "iscroll" object is defined .
function scrollToElement($element) {
if ($element.size() > 1) {
throw new Error("Cannot be a node!");
};
var offset = $element.offset().top;
var to = -(offset - iscroll.y);
to = (iscroll.maxScrollY > to) ? iscroll.maxScrollY : to;
iscroll.scrollTo(0, to);
}

Resources