Reputation: 394
I've a layout template with a left sidebar where I show information of Location passed entities as an array.
Also in this template, I show a object Map with all of this locations.
I want to do click on a Location of my sidebar and then on the same template show another object Map replacing the previous with information of this Location. Keeping the sidebar with the information and not doing new queries on the database.
How to achieve this?
Ajax? Conditional layout?
I read this article but I don't understand how to solved my problem: http://twig.sensiolabs.org/doc/recipes.html#overriding-a-template-that-also-extends-itself
PD: I'm using Twig template and Symfony2
Upvotes: 1
Views: 1195
Reputation: 20191
You could have a separate template for printing object map and, as you guessed, this would have to be done using AJAX
. You would pass the data you want to show on map (not id as you don't want to query database again) and the controller would return formatted HTML.
However, this seems to me a bit overkill. I would always consider doing JS
(with optional framework) in order to swap the content of sidebar with Map
object.
It really depends on which map API do you use. If it could be controlled via JS
I would look no further. It it could not, well then, AJAX
is your natural choice....
OK, what you should do is create initial Map object that will be modified later on:
var theMap = null;
function initializeMap(){
var mapOptions = {
center: new google.maps.LatLng(some_latitude, some_longitude),
zoom: 8, // goes from 0 to 18
mapTypeId: google.maps.MapTypeId.ROADMAP
};
theMap = new google.maps.Map(document.getElementById("map_canvas"),mapOptions);
// you must have some element with ID = 'map_canvas'
}
some_latitude
and some_longitude
are fairly unimportant as you will most likely set new coordinates in a few moments.
Now assuming (but not crucial at all) that you use some of the JS
frameworks (I prefer jQuery
) you could bind click event to those location links:
var onlyMarker = null;
$('.location').click(function(){
var $t = $(this);
var newLatLang = new google.maps.LatLng($t.attr('data-lat') ,$t.attr('data-lng'));
if ( onlyMarker == null ) {
onlyMarker = new google.maps.Marker({
position: newLatLang
map: theMap,
title: $t.attr('title')
});
}else{
onlyMarker.setPosition(newLatLang);
}
});
Now, relying on HTML5's 'data-*' attibutes is not good idea in particular as if you use any other version lower you will most likely end-up with invalid markup. The workaround is to for link (<a>
) to carry id/key to LatLng
object, for example:
// initially generated from `AJAX` or in `Twig` loop
var allLatlangs = [
new google.maps.LatLngf(some_latitude, some_longitude),
new google.maps.LatLngf(some_latitude, some_longitude),
new google.maps.LatLngf(some_latitude, some_longitude),
];
$('.location').click(function(){
var id = $(this).attr('id');
var newLatLang = allLatLang(id);
//....
// everything else is the same
// ....
});
Don't forget to include Maps API with proper API key:
https://maps.googleapis.com/maps/api/js?key=API_KEY_HERE&sensor=true
In order to obtain valid API key follow this link: API KEY HOW-TO
This link basically covers key steps that I have described here so study it and it should all come together nicely.
Also, if you're unsure how to retrieve some things from Maps you should consult reference: REFERENCE which has every method call described pretty good
Remember not to execute any of this code until everything is being loaded.
Hope this helped a bit :)
Upvotes: 2