I am using Leaflet to produce different maps on a button click, but the map is not filling the whole area.
The click event grabs various longitudes and latitudes that were stored in my database and sent to the page in a datatable.
The button click looks like this:
$('#datatable').on('click', 'tr > td > a.mapClick', function(e)
{
e.preventDefault();
var rampName = $(this).attr('data-rampname');
var delName = $(this).attr('data-delname');
var actramplat = parseFloat($(this).attr('data-actramplat'));
var actramplng = parseFloat($(this).attr('data-actramplng'));
var actdellat = parseFloat($(this).attr('data-actdellat'));
var actdellng = parseFloat($(this).attr('data-actdellng'));
$('#rampName').val(rampName);
$('#delname').val(delName);
$('#actramplat').val(actramplat);
$('#actramplng').val(actramplng);
$('#actdellat').val(actdellat);
$('#actdellng').val(actdellng);
initMap(rampName, delname, actramplat, actramplng, actdellat, actdellng);
$('#mapModal').modal('show');
});
function initMap(rampName, delname, actramplat, actramplng, actdellat, actdellng)
{
//window.dispatchEvent(new Event('resize')); <-- tried this
//map.invalidateSize(); <-- also tried this
var map = L.map('map').setView([actreclat,actreclng], 8);
L.tileLayer('https://api.maptiler.com/maps/streets/{z}/{x}/{y}.png?key=zAlHsNvo6jxv4ENZxW3R', {
attribution: '© MapTiler © OpenStreetMap contributors'
}).addTo(map);
}
In my header, I styled the map as follows:
<style>
height:275px;
width:100%;
</style>
In an attempt to prevent a duplicate post, I attempted to use answers from the following post to no avail:
Data-toggle tab does not download Leaflet map
The map continues to NOT fill the whole area.
What adjustments do I need in order to ensure the map fills the whole area?
You're on the right track - the call to invalidateSize() needs to go after the element which contains the map is made visible - which is presumably like this
$('#mapModal').modal('show');
map.invalidateSize();
I added the following modal command and threw the function call inside of it:
$('#datatable').on('click', 'tr > td > a.mapClick', function(e)
{
e.preventDefault();
var rampName = $(this).attr('data-rampname');
var delName = $(this).attr('data-delname');
var actramplat = parseFloat($(this).attr('data-actramplat'));
var actramplng = parseFloat($(this).attr('data-actramplng'));
var actdellat = parseFloat($(this).attr('data-actdellat'));
var actdellng = parseFloat($(this).attr('data-actdellng'));
$('#rampName').val(rampName);
$('#delname').val(delName);
$('#actramplat').val(actramplat);
$('#actramplng').val(actramplng);
$('#actdellat').val(actdellat);
$('#actdellng').val(actdellng);
$('#mapModal').modal('show');
// added below modal function
$("#actionMatchbackModal").on("shown.bs.modal", function () {
initMap(rampName, delname, actramplat, actramplng, actdellat, actdellng);
});
});
Then, inside the actual function, I added the map.invalidateSize() after the creation of the map variable:
function initMap(rampName, delname, actramplat, actramplng, actdellat, actdellng)
{
var map = L.map('map').setView([actreclat,actreclng], 8);
map.invalidateSize();
L.tileLayer('https://api.maptiler.com/maps/streets/{z}/{x}/{y}.png?key=zAlHsNvo6jxv4ENZxW3R', {
attribution: '© MapTiler © OpenStreetMap contributors'
}).addTo(map);
}
Now the map fills the whole area.
Related
Hello I'm trying to call to a function when one make a click on some elements.
I'm doing a form using symfony php framework. Following this:
http://symfony.com/doc/current/cookbook/form/form_collections.html#template-modifications
I readed this:
https://stackoverflow.com/a/1207393/4386551
But it does not work with a.delete elements, it works for a.add only.
var $collectionHolder;
// setup an "add a tag" link
var $addTagLink = $('Add a tag');
var $newLinkLi = $('<li></li>').append($addTagLink);
jQuery(document).ready(function() {
// Get the ul that holds the collection of tags
$collectionHolder = $('ul.details');
// add the "add a tag" anchor and li to the tags ul
$collectionHolder.append($newLinkLi);
// count the current form inputs we have (e.g. 2), use that as the new
// index when inserting a new item (e.g. 2)
$collectionHolder.data('index', $collectionHolder.find(':input').length);
$addTagLink.on('click', function(e) {
// prevent the link from creating a "#" on the URL
e.preventDefault();
// add a new tag form (see next code block)
addTagForm($collectionHolder, $newLinkLi);
});
$(".details").on("click", "a.add", function (){alert("HEY");});
$(".details").on("click", "a.delete", function (){alert("HEY");});
});
function addTagForm($collectionHolder, $newLinkLi) {
// Get the data-prototype explained earlier
var prototype = $collectionHolder.data('prototype');
// get the new index
var index = $collectionHolder.data('index');
// Replace '__name__' in the prototype's HTML to
// instead be a number based on how many items we have
var newForm = prototype.replace(/__name__/g, index);
// increase the index with one for the next item
$collectionHolder.data('index', index + 1);
// Display the form in the page in an li, before the "Add a tag" link li
var $newFormLi = $('<li></li>').append(newForm);
$newLinkLi.before($newFormLi);
addTagFormDeleteLink($newFormLi);
}
function addTagFormDeleteLink($tagFormLi) {
var $removeFormA = $('delete this tag');
$tagFormLi.append($removeFormA);
$removeFormA.on('click', function(e) {
// prevent the link from creating a "#" on the URL
e.preventDefault();
// remove the li for the tag form
$tagFormLi.remove();
//reload_total();
});
}
what's wrong with a.delete and jquery.on?
Try to change to:
$(".details a.add").on("click", function (){alert("HEY");});
$(".details a.delete").on("click", function (){alert("HEY");});
Or this:
$(".details").on("click", "a.add, a.delete", function (){alert("HEY");});
I have a php script that I call that returns html in a way that it can be directly inserted into a container or the body and just work (E.X. '<image id="trolleyLogoEdge" class="pictureFrame party" src="tipsyTrixy.png" >'). After appending this text to a div the selector $('#pictureFrame > img:first') won't work. I'm not using event handlers or anything so I don't know why I'm having an issue. My code worked fine when I just had the image tags in the div without any manipulation so I'm assuming it must be a selector issue. I have tested my php output and it is exactly matching the html that was in the div before I decided to dynamically populate the div.
var classType = '';
var classTypePrev = '';
var width = $(window).width();
var height = $(window).height();
var size = (height + width)/2;
var time = 0;
$( document ).ready(function()
{
$.post( "pictureDirectory.php", function( data )
{
$('#picureFrame').append(data);
startSlideshow($('#pictureFrame > img:first'));
});
});
window.onresize = function()
{
width = $(window).width();
};
function startSlideshow(myobj)
{
classType = $(myobj).attr('class').split(' ')[1];
if(classTypePrev != classType)
{
$('.picDescription').animate({'opacity': "0"},{duration: 2000,complete: function() {}});
$('.picDescription.' + classType).animate({'opacity': "1"},{duration: 3000,complete: function() {}});
}
classTypePrev = classType;
myobj.animate({left: "-=" + ((width/2)+ ($(myobj).width()/2) - 150), opacity: '1'},{
duration: 5000,
'easing': 'easeInOutCubic',
complete: function() {}}).delay(2000).animate({left: "-=" + ((width/2)+ ($(myobj).width()/2) + 150), opacity: '0'},{
duration: 5000,
'easing': 'easeInOutCubic',
complete: function()
{
$(myobj).css("left", "100%");
}
});
setTimeout(function()
{
var next = $(myobj).next();
if (!next.length)
{
next = myobj.siblings().first();
}
startSlideshow(next)},9000);
}
Your code that appends the data to the frame has a typo in the ID selector.
$.post( "pictureDirectory.php", function( data )
{
$('#picureFrame').append(data);
^^here
startSlideshow($('#pictureFrame > img:first'));
});
It should probably be
$('#pictureFrame').append(data);
.find() gets the descendants of each element in the current set of matched elements.
> selects all direct child elements specified by "child" of elements specified by "parent".
Try:
startSlideshow($("#pictureFrame").find("img:first"));
If img is not direct child of #pictureFrame, .find() should work.
You should know the difference between
Delegated Event
Direct Event
check this for the difference between direct and delegated events.
If we were to click our newly added item, nothing would happen. This is because of the directly bound event handler that we attached previously. Direct events are only attached to elements at the time the .on() method is called. In this case, since our new anchor did not exist when .on() was called, it does not get the event handler.
check this link to official JQuery Document for further clarification.
Hi I am trying to append facebook friends thumbnail in list item and add trigger on each of them. but now it trigger the click but it's only getting fbid of the last appended item inside the click callback. How can I attach click event on each of them correctly?
for(var i=0;i<obj.photo.length;i++) {
var img=$('<img src="https://graph.facebook.com/'+obj.photo[i]['fb_id']+'/picture" />');
var anchor=$('');
var li = $('<li></li>');
var fbul = $('#fb_friends');
anchor.append(img);
li.append(anchor);
fbul.append(li);
anchor.click(function(){
alert(anchor.attr('id'));
});
}
the problem is because, you are using a closure variable anchor inside your callback function for click event. The solution to this problem is to fetch the clicked element from the event properties as given below. Inside the event handler method this points to the element to which the handler is registered to.
anchor.click(function() {
var $this = $(this);
alert($this.attr('id'));
});
But since you are working with dynamic element I recommend using event delegation with .on()
var fbul = $('#fb_friends');
fbul.on('click', 'a', function() {
var $this = $(this);
alert($this.attr('id'));
})
for (var i = 0; i < obj.photo.length; i++) {
var img = $('<img src="https://graph.facebook.com/' + obj.photo[i]['fb_id']
+ '/picture" />');
var anchor = $('');
var li = $('<li></li>');
anchor.append(img);
li.append(anchor);
fbul.append(li);
}
I have a Google map that I want to automatically load with a prepopulated route (taken from a series of PHP form submissions).
Currently, the PHP forms culminate in a page that has a Google Map on it, and some drop-down boxes with the start and end points prepopulated (from their previous PHP form submissions), and an onChange function on the drop-down menus which calculates the route (onChange="calcRoute();", in the example below). This works fine but, in reality, every final form ends up with just one option for the route. Therefore, getting the user to "select" the start points and end points for the route is worthless - there is only one option in each drop down menus, so I might as well load those options and the calculated route between them automatically when the page loads.
Is there any way of doing this?
My directions function looks like this:
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<?PHP
$Start_latLng = $_POST["start-latitude"] . ", " . $_POST["start-longitude"];
$End_latLng = $_POST["end-latitude"] . ", " . $_POST["end-longitude"];
?>
<script>
var directionDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
function initialize() {
directionsDisplay = new google.maps.DirectionsRenderer();
var mapOptions = {
zoom:7,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: new google.maps.LatLng(54.219218, -2.905669)
}
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
directionsDisplay.setMap(map);
}
function calcRoute() {
var start = document.getElementById('start').value;
var end = document.getElementById('end').value;
var request = {
origin:start,
destination:end,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
}
</script>
...and my dropdown menus are populated by the results of the PHP $_POST functions.
Obviously, I need wait for the map to load before I can calculate the route, so a pause might need to be injected - any ideas?
Thank you to #Robot Woods:
Could you just fire calcRoute(); as the last line of your initialize function? – Robot Woods
I'm wishing to render multiple charts using mysql data, there will be more or less charts depending on a particular search. I've successfully created a single chart, and my php file echoes the required json format nicely.
Now, what I would like is to be able to loop over an array and draw new charts based on the array vales being parsed to the php which in turn provides different json data to be rendered.
by the way, my javasript is very limited so here goes my code and thoughts:
<script type="text/javascript">
$(function () {
var chart;
var venue = <?php echo json_encode($venue_name); ?>; /* parsed to php file */
var distances = <?php echo json_encode($data); ?>; /* array to be looped over */
$(document).ready(function() {
var options = {
....
series: []
....
};
//
$.each(distances, function() {
$.each(this, function(name, value) {
// do some ajax magic here:...
GET 'myphpfile.php?venue='+venue+'&'+distances
function drawNewChart(){
$('#mainSite').append('<div id="container" style="float:left; display:inline"></div>');
chart = new Highcharts.Chart(options);
});
});
</script>
What I have learnt is that I cannot loop an include php file which has the completed php and jquery...
this will create other charts. every time u want create new chart , u must give new name chart like i do chart2
paste this bellow and it will give you other chart.
<script type="text/javascript">
$(function () {
var chart2;
var venue2 = <?php echo json_encode($venue_name); ?>; /* <---use other variable here of $venue_name */
var distances2 = <?php echo json_encode($data); ?>; /* <---use other variable of $data */
$(document).ready(function() {
var options = {
....
series: []
....
};
//
$.each(distances2, function() {
$.each(this, function(name, value) {
// do some ajax magic here:...
GET 'myphpfile.php?venue2='+venue2+'&'+distances2
function drawNewChart(){
$('#mainSite').append('<div id="container" style="float:left; display:inline"></div>');
chart2 = new Highcharts.Chart(options);
});
});
</script>
Instead of using many variables, you can push your charts to array.
var charts = [];
charts.push(new Highcharts(options));
Then you can avoid of using index etc.