I'm pulling data from mySQL through Laravel, generating a map, which works well, now I just want buttons that jump to each marker. For some reason it only goes to the last position.
$.ajax({
url: '/lookup',
type: "post",
data: {'lat':$("#lat").val() ,'lng':$("#lng").val(), '_token': $('input[name=_token]').val()},
success: function(data){
var nearest = data;
var markers = data;
// Loop through our array of markers & place each one on the map
for( i = 0; i < markers.length; i++ ) {
var position = new google.maps.LatLng(markers[i].lat, markers[i].lng);
bounds.extend(position);
marker = new google.maps.Marker({
position: position,
map: map,
title: markers[i].name,
icon: 'http://website.com/assets/images/icons/love_google.png'
});
google.maps.event.addDomListener(document.getElementById("link_"+i), "click", function(e) {
alert(position);
map.setCenter(position);
});
// Allow each marker to have an info window
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
//infoWindow.setContent(infoWindowContent[i][0]);
infoWindow.setContent('<div class="info_content"><h3>' + markers[i].name + '</h3><p>' + markers[i].address + '<br />' + markers[i].city + ', ' + markers[i].state + ' ' + markers[i].zip + '<br />' + markers[i].phone + '</p></div>' );
infoWindow.open(map, marker);
}
})(marker, i));
}
}
});
You should construct the event listener for the button click in the same way you're doing it for the marker click. The problem is that position at the time you click the button will be just whatever that variable is at that point in time, not whatever it was on the iteration of the loop when you constructed the event listener.
Try something like:
google.maps.event.addDomListener(document.getElementById("link_"+i), "click", (function(position) {
return function() {
alert(position);
map.setCenter(position);
}
})(position));
Related
I have Ajax function in my Laravel project. I'm taking data from db and send them on Leaflet map.
When I have setInterval, markers starts to duplicate. Unfortunately removeLayer can not help me, or I'm ussing it wrong.
This is my code
function callAjax() {
$.ajax({
url: '/device_new',
type: 'GET',
dataType: 'json',
success: function(data) {
markerLayer.removeLayer();
var markerLayer = L.featureGroup().addTo(map);
var coordinates = data;
for (var i = 0; i < coordinates.length; i++) {
if (coordinates[i].x && coordinates[i].y) {
marker = L.marker([coordinates[i].x, coordinates[i].y])
.bindPopup("Device: " + coordinates[i].device_type + '<br>' + "Time: " + coordinates[i].datetime)
marker.addTo(markerLayer);
}
}
map.fitBounds(markerLayer.getBounds());
},
});
setInterval(callAjax, 3000);
}
Any idea what could be a problem?
removeLayer(<Layer>) removes a single given layer from the featureGroup.
You need
markerLayer.clearLayers()
to remove all layers.
Change your code to:
function callAjax() {
$.ajax({
url: '/device_new',
type: 'GET',
dataType: 'json',
success: function(data) {
markerLayer.clearLayers();
var coordinates = data;
for (var i = 0; i < coordinates.length; i++) {
if (coordinates[i].x && coordinates[i].y) {
marker = L.marker([coordinates[i].x, coordinates[i].y])
.bindPopup("Device: " + coordinates[i].device_type + '<br>' + "Time: " + coordinates[i].datetime)
marker.addTo(markerLayer);
}
}
map.fitBounds(markerLayer.getBounds());
},
});
setInterval(callAjax, 3000);
}
function loadMap() {
// Where you want to render the map.
var element = document.getElementById('osm-map');
// Height has to be set. You can do this in CSS too.
element.style = 'height:405px;', 'width:500px;';
// Create Leaflet map on map element.
map = L.map(element);
// Add OSM tile leayer to the Leaflet map.
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
map.pm.addControls({
position: 'topleft',
});
//********************** ADD HERE **************
var markerLayer = L.featureGroup().addTo(map);
}
In addition to this question Highlight text when hover imagemap area and vice versa - using imagemapster I'm searching for a solution to add a class to an image outside the imagemap. The intention is when hovering on a part of the imagemap a line is showing beneath a image above the imagemap. For an example and partly working script (which is based on the question above): http://jsfiddle.net/kyzho2v4/3/
jQuery(document).ready(function ($) {
$('#house').mapster({
mapKey: 'name',
singleSelect: true,
fillOpacity: 0.6,
fillColor: 'FF0000',
//
onMouseover: function (evt) {
var parts = evt.key.split('-');
var part = parts[1];
highlightArea(part);
},
//
onMouseout: function (evt) {
var parts = evt.key.split('-');
var part = parts[1];
highlightAreaX(part);
}
});
//
$('a').hover(function () {
var parts = $(this).closest('div').attr('class').split('-');
var part = parts[2];
highlightArea(part);
});
//
$('a').mouseleave(function () {
var parts = $(this).closest('div').attr('class').split('-');
var part = parts[2];
highlightAreaX(part);
});
});
//
function highlightArea(key) {
$('area[name=part-' + key + ']').mouseenter();
$('a').addClass('line');
$('div.menu-item-' + key + ' a').addClass('line');
}
//
function highlightAreaX(key) {
$('area[name=part-' + key + ']').mouseout();
$('a').removeClass('line');
$('div.menu-item-' + key + ' a').removeClass('line');
}
Posted OP's answer as an answer:
I found a solution, so for those who are searching the same thing: I only added a new css class (line1) and changed the jquery script a little bit: http://jsfiddle.net/88c0odmn/7/
//
function highlightArea(key) {
$('area[name=part-' + key + ']').mouseenter();
$('div.menu-item-' + key + ' a').addClass('line1');
}
//
function highlightAreaX(key) {
$('area[name=part-' + key + ']').mouseout();
$('a').removeClass('line');
$('div.menu-item-' + key + ' a').removeClass('line1');
}
jQuery:
// Load message
(function loadAdmin() {
$.ajax({
type: 'POST',
data: 'c_id=' + $(this).data('c_id') + '&offset=' + $(this).data('offset'), //'foo='+ bar+'&calibri='+ nolibri,
dataType: 'json',
url: $("#webroot").text() + 'chats/loadMsg',
success: function (data) {
var id = 0;
$.each(data, function (i, item) {
if (item.Chat.status == 'active') {
$('.temp_msg').remove();
}
if (!$('#' + item.Chat.id)[0]) {
if (item.Chat.admin_message) {
$('<div class="msg_a" id="' + item.Chat.id + '">' + item.Chat.admin_message + '</div>').insertBefore('.' + $(this).data('c_id') + ' .msg_push');
}
if (item.Chat.client_message) {
$('<div class="msg_b" id="' + item.Chat.id + '">' + item.Chat.client_message + '</div>').insertBefore('.' + $(this).data('c_id') + ' .msg_push');
}
$('.msg_body').scrollTop($('.msg_body')[0].scrollHeight);
}
id = item.Chat.id;
});
$('.' + c_id + ' .msg_head').data('offset', id)
},
complete: function () {
// Schedule the next request when the current one's complete
setTimeout(loadAdmin, 10000);
}
});
})();
// END load message
I set c_id statically.This works fine. But I want to do this same action for all activated class.
This is something like this:
$('.activated').each(function () {
// do ajax call
loadAdmin();
});
Here crucial situation is for first iteration there start a recursion of loadAdmin(); function calling, then again start first iteration and never step up to second iteration. How can I meet my situation. Thanks
you can use setInterval() function for complete your requirements.
Like this :
$('.activated').each(function () {
// do ajax call
setInterval(loadAdmin(), 10000); // This will call this function in every 10 sec
});
Try this. I hope you will found it.
I am developing an app where I use 2 API's a.k.a Instagram API and Google Map API. Using AJAX, I get the first set of Images filtered by a tag name. In the 1st set we receive 20 images. Among the received images, the images that have the latitude and longitude info (geotagged images) are displayed on the map.
Now the first time when my page loads, I cannot see the map. But when I press the load more button to get the next set of images, the Map works fine showing my previous images too.
Here is the code for what happens on page load:
$( window ).load(function() {
$.ajax({
type: "GET",
url: "https://api.instagram.com/v1/tags/nyc/media/recent?client_id=02e****",
dataType:'JSONP',
success: function(result) {
onAction(result, 2, tag);
instaMap(result, 2, from);
}
});
});
These are the functions being called:
/**
* [initialize description]
* Initialize the map with markers showing all photos that are geotagged.
*/
var initialize = function(markers) {
var bounds = new google.maps.LatLngBounds(),
mapOptions = {
scrollwheel: false,
mapTypeId: 'roadmap',
center: new google.maps.LatLng(22.50, 6.50),
minZoom: 2
},
gmarkers = [],
map,
positions,
markCluster;
markers = remDuplicate(markers);
// Info Window Content
var infoWindowContent = [];
for (var j = 0; j < markers.length; j++ ) {
var content = [
'<div class="info_content">' +
'<h3>' + markers[j][2] + '</h3>' +
'<a href="' + markers[j][3] + '" target="_blank">' +
'<img src="' + markers[j][4] + '" style="z-index:99999">' + '</a>' +
'</div>'
];
infoWindowContent.push(content);
}
// Display a map on the page
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
map.setTilt(45);
// Display multiple markers on a map
var oms = new OverlappingMarkerSpiderfier(map);
var infoWindow = new google.maps.InfoWindow(), marker, i;
// Loop through our array of markers & place each one on the map
for( i = 0; i < markers.length; i++ ) {
positions = new google.maps.LatLng(markers[i][0], markers[i][1]);
marker = new google.maps.Marker({
position: positions,
map: map,
animation:google.maps.Animation.BOUNCE,
title: markers[i][2]
});
oms.addMarker(marker);
// Allow each marker to have an info window
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infoWindow.close();
infoWindow.setContent(infoWindowContent[i][0]);
infoWindow.open(map, marker);
map.setCenter(marker.getPosition());
};
})(marker, i));
gmarkers.push(marker);
}
google.maps.event.addListener(map, 'click', function() {
infoWindow.setMap(null);
});
markCluster = new MarkerClusterer(map, gmarkers);
// Override our map zoom level once our fitBounds function runs (Make sure it only runs once)
var boundsListener = google.maps.event.addListener((map), 'bounds_changed', function(event) {
map.setZoom(2);
google.maps.event.removeListener(boundsListener);
});
};
/**
* [onAction]
* OnAction() function helps in loading non-geotagged pics.
*
* #param {[type]} result [Result retruned from the Instagram API in json format]
* #param {[type]} likey [hearts the user has entered as per which the posts will be filtered]
*/
var onAction = function (result, likey, tag) {
$('.load-pics').remove();
if (result.pagination.next_url) {
paginate = removeURLParameter(result.pagination.next_url, 'count');
}
$.each(result, function(key, value) {
if (key === 'data') {
$.each(value, function(index, val) {
liked = val.likes.count;
link = val.link;
imgUrl = val.images.low_resolution.url;
locations = val.location;
if (liked >= likey) {
if (locations === null) {
output = '<li class="img-wrap">' + '<div class="main-img">' +
'<a href="' + link + '" target="_blank">' +
'<img src="' + imgUrl + '" ><span class="hover-lay"></span></a>' +'<p>' +
'<span class="heart"></span><span class="likes-no">' + liked + '</span>' +
'<span class="comment-box"></span><span class="comment-no">' +
val.comments.count + '</span> ' + '</p>' + '</div>' +
'<div class="img-bottom-part">'+ '' + '<div class="headin-hastag">' +
'by ' + '<h2>Sebastien Dekoninck</h2>#hello <span>#kanye</span> #helloagain #tagsgohere</div>'
+'</div></li>';
$('#instafeed').append(output);
}
}
});
}
});
if ($('#instafeed').children().length === 0) {
alert('There are no pics with ' + likey + ' likes or #' + tag + ' was not found.');
} else {
// $('.not-geo').remove();
// $('#instafeed').before('<button class="not-geo">Click To See Images That Are Not Geotagged <img src="assets/imgs/down.png" ></button>');
}
$('#instafeed').append('<div class="load-pics"><button id="show-more">Show more <span></span></button> </div>');
};
/**
* [instaMap]
* instaMap() will be the function which will deal with all map based functionalities.
*/
var instaMap = function(result, likey, from) {
$('.load-mark').remove();
if (result.pagination.next_url) {
pagiMap = removeURLParameter(result.pagination.next_url, 'count');
}
$.each(result, function(key, value) {
if (key === 'data') {
$.each(value, function(index, val) {
liked = val.likes.count;
link = val.link;
imgUrl = val.images.low_resolution.url;
locations = val.location;
if (liked >= likey) {
if (locations && locations.latitude !== null) {
tempArr = [
locations.latitude,
locations.longitude,
val.user.username,
val.link,
val.images.low_resolution.url
];
mark.push(tempArr);
}
}
});
}
});
if (mark.length) {
initialize(mark);
$('.map-parent-wrapper').append('<div class="load-mark"><button id="show-mark">See More </button></div>');
} else {
alert('No geotagged pics found in the retrieved set. Click see more');
$('.map-parent-wrapper').append('<div class="load-mark"><button id="show-mark">See More </button></div>');
}
};
I have created a See More button to retrieve the next set of images and load those on the Map. When clicking see more, everything seems to work fine. Not sure why it's happening so. Console.log does not show any error. Also, all the values I feed does flow appropriately. I even tried clearing cache. Not sure, why it's happening.
If instaMap is the function which is going to handle all your map based functionality, it has to be the one that loads map in your $( window ).load function ();
Otherwise, if you want Google maps to load on initial window load you need to put below in there:
google.maps.event.addDomListener(window, 'load', initialize);
Im having trouble getting my CKEditor to work properly.
I am inserting my instance using Jquery. And set up my own Ajax save function for the editor.
My instances are always inserted just fine. The editor appears as it should, - and seem to work.
HOWEVER: it turns out that the 2. time I insert the instance, - the textarea is not being updated - thus no updated data sent to the Ajaxcall. It sends the old data.
After sending to the ajax call, I destroy my instance:
CKEDITOR.instances[currentInstance].destroy();
And the editor seem to be destroyed properly, every time.
OnClick I then re-insert the editor (Same instancename. I also remove the textarea when I destroy the instance, and then reinsert the textarea, when I reinsert the instance. Same textareaname).
Can anyone tell me why I can insert the instance again and again, - but the editor only updates the textarea the first time?
Ive tried:
for ( var instance in CKEDITOR.instances ) {
CKEDITOR.instances[instance].updateElement(); }
inserted in the save function - just before the ajaxcall. But still no update.
This is the build of the instance. Via Jquery I insert this as html() :
<script type="text/javascript">
CKEDITOR.replace('tekstindhold233',
{ height:'250px',width:'575px' });
</script>
And heres the savefunction:
CKEDITOR.plugins.add('popwebsave',
{
init: function(editor)
{
var pluginName = 'popwebsave';
editor.addCommand( pluginName,
{
exec : function( editor )
{
for ( var i in CKEDITOR.instances ){
var currentInstance = i;
break;
}
for ( var instance in CKEDITOR.instances ) {
CKEDITOR.instances[instance].updateElement(); }
var sprog = $('#lan_holder').text();
var vis = $('#vis_holder').text();
var pageId = $('#pageId_holder').text();
var tekstIndhold = CKEDITOR.instances[currentInstance].getData();
var tekstIndholdBox = currentInstance.replace('tekstindhold','');
var contentOrden = $('#content_orden' + tekstIndholdBox).text();
var dataString = 'lan=' + sprog + '&tekstindhold=' + tekstIndhold + '&eid=' + tekstIndholdBox + '&vis=' + vis + '&id=' + pageId + '&contentOrden=' + contentOrden;
$("#tekstindhold_box" + tekstIndholdBox).animate({
opacity: 0
} , {
duration: 500,
complete: function() {
$("#textarea_box" + tekstIndholdBox).text('');
$.ajax({
type: "POST",
url: "includes/JQ_opdater_tekst.php",
data: dataString,
dataType: "json",
cache: false,
success: function(databack){
$("#textarea_box" + tekstIndholdBox).animate({
height: 100
}, 500, function() {
$("#tekstindhold_box" + tekstIndholdBox).html(databack.tekstindhold_db);
$("#tekstindhold_box" + tekstIndholdBox).animate({
opacity: 1
}, 500, function() {
CKEDITOR.instances[currentInstance].destroy();
});
});
}
});
}
});
},
canUndo : true
});
/*
editor.addCommand(pluginName,
new CKEDITOR.dialogCommand(pluginName)
);
*/
editor.ui.addButton('Popwebsave',
{
label: 'Gem',
command: pluginName,
className : 'cke_button_save'
});
}
});
Nevermind!
I figured it out. Turns out that the instance needs to be present in the DOM, on destroy() I switched the order of events around so that destroy() happens first, and THEN removed the textarea. Works just fine now.