AJAX loading indicator - ajax

I use this AJAX code:
<script language="javascript" type="text/javascript">
<!--
//Browser Support Code
function ajaxFunction(){
var ajaxRequest; // The variable that makes Ajax possible!
try{
// Opera 8.0+, Firefox, Safari
ajaxRequest = new XMLHttpRequest();
} catch (e){
// Internet Explorer Browsers
try{
ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try{
ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e){
// Something went wrong
alert("Your browser broke!");
return false;
}
}
}
// Create a function that will receive data sent from the server
ajaxRequest.onreadystatechange = function(){
if(ajaxRequest.readyState == 4){
var ajaxDisplay = document.getElementById('ajaxDiv');
ajaxDisplay.innerHTML = ajaxRequest.responseText;
}
}
var age = document.getElementById('age').value;
var wpm = document.getElementById('wpm').value;
var sex = document.getElementById('sex').value;
var queryString = "?age=" + age + "&wpm=" + wpm + "&sex=" + sex;
ajaxRequest.open("GET", "file.php" + queryString, true);
ajaxRequest.send(null);
}
//-->
</script>
How to indicate AJAX loading?

Common scenario is to show animated gif image or change mouse cursor on start of ajax request and at end.
Gif is much simpler. Something like (I am using JQuery Syntax):
For start:
$("#progressIndicator").show();
In your onreadystatechange handler
$("#progressIndicator").hide();

If your using JQuery you can do something like this:
$("#progressIndicator").show();
var age = $('#age')[0].value;
var wpm = $('#wpm')[0].value;
var sex = $('#sex')[0].value;
var queryString = "?age=" + age + "&wpm=" + wpm + "&sex=" + sex;
$.get("file.php" + queryString, function (data) {
$("ajaxDiv").html(data);
$("#progressIndicator").hide();
})
you can see more about the JQuery get method
here

You can bind the showing/hiding globally in your app (or just in some part of it) with the following events:
$(document).on({
ajaxStart: function () { $body.addClass("loading"); },
ajaxStop: function () { $body.removeClass("loading"); }
});
And then you define the class loading:
/* Start by setting display:none to make this hidden.
Then we position it in relation to the viewport window
with position:fixed. Width, height, top and left speak
for themselves. Background we set to 80% white with
our animation centered, and no-repeating */
.modal {
display: none;
position: fixed;
z-index: 1000;
top: 0;
left: 0;
height: 100%;
width: 100%;
background: rgba( 255, 255, 255, .8 ) url('../Images/Loader.gif') 50% 50% no-repeat;
}
/* When the body has the loading class, we turn the scrollbar off with overflow:hidden */
body.loading {
overflow: hidden;
}
/* Anytime the body has the loading class, our modal element will be visible */
body.loading .modal {
display: block;
}
In this way you don't need to manage the loading effect for every ajax call and you can maintain a consistent style through the entire application.

Related

lazy load doesnt work with hidden elements

this is my simple test code for lazy load
http://codepen.io/kevkev/pen/bVVGdE
it works so far .. but the thing is that hidden images in an onclick function for buttons etc. doesnt work!
(watch through my code and scroll to end and push the button)
you can see in the network feedback that it already had load the images.
i could figure out that the problem is "display:none"
.pop {
display:none;
z-index:99;
position:absolute;
width:100%;
height:auto;
background:inherit;
}
Because display: none; elements are unknown in position. And the lazyloader doesn't know, when and if you change this. Therefore it decides to eager load it. If you want a lazyloader that automatically detects this use https://github.com/aFarkas/lazysizes/.
As alternative I would recommend justlazy, because it's more lightweight and don't uses jQuery.
1. Define placeholder (similar to that what you have done):
<span data-src="path/to/image" data-alt="alt" data-title="title"
class="placeholder">
</span>
2. Initialize lazy loading after your button click:
$(document).ready(function () {
$("#art").click(function () {
$("#art_pop").fadeIn(300);
Justlazy.registerLazyLoadByClass("placeholder", {
// image will be loaded if it is 300 pixels
// below the lower display border
threshold: 300
});
});
// other code ..
});
thanks guys! but I also got a working solution on this:
http://codepen.io/kevkev/full/meebpQ/
$(document).ready(function () {
$("#art").click(function () {
$("#art_pop").fadeIn(300);
});
$(".pop > span, .pop").click(function () {
$(".pop").fadeOut(600);
});
});
;(function($) {
$.fn.unveil = function(threshold, callback) {
var $w = $(window),
th = threshold || 0,
retina = window.devicePixelRatio > 1,
attrib = retina? "data-src-retina" : "data-src",
images = this,
loaded;
this.one("unveil", function() {
var source = this.getAttribute(attrib);
source = source || this.getAttribute("data-src");
if (source) {
this.setAttribute("src", source);
if (typeof callback === "function") callback.call(this);
}
});
function unveil() {
var inview = images.filter(function() {
var $e = $(this);
if ($e.is(":hidden")) return;
var wt = $w.scrollTop(),
wb = wt + $w.height(),
et = $e.offset().top,
eb = et + $e.height();
return eb >= wt - th && et <= wb + th;
});
loaded = inview.trigger("unveil");
images = images.not(loaded);
}
$w.on("scroll.unveil resize.unveil lookup.unveil", unveil);
unveil();
return this;
};
})(window.jQuery || window.Zepto);
/* OWN JAVASCRIPT */
$(document).ready(function() {
$("img").unveil(200, function() {
$(this).load(function() {
this.style.opacity = 1;
});
});
});

Fusion Tables fusiontips mouseover event not working

I created a map using Fusion Tables today, and I'm about 90% of where I need to be, but I'm totally stuck on enabling the mouseover event on my map. Basically I want the county name to appear as one hovers over the map. I've taken the sample code from here:
http://gmaps-utility-gis.googlecode.com/svn/trunk/fusiontips/docs/examples.html
I think I've filled in the required info correctly. I generated the HTML/JS map automatically from Fusion Tables. Here's my live map: http://www.casalett.net/map/map.html
Any and all help would be appreciated!
Here's the code:
<script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false&v=3"></script>
<script src="js/fusiontipsV1.js" type="text/javascript"></script>
<script type="text/javascript">
function initialize() {
google.maps.visualRefresh = true;
var isMobile = (navigator.userAgent.toLowerCase().indexOf('android') > -1) ||
(navigator.userAgent.match(/(iPod|iPhone|iPad|BlackBerry|Windows Phone|iemobile)/));
if (isMobile) {
var viewport = document.querySelector("meta[name=viewport]");
viewport.setAttribute('content', 'initial-scale=1.0, user-scalable=no');
}
var mapDiv = document.getElementById('googft-mapCanvas');
//mapDiv.style.width = isMobile ? '100%' : '1000px';
//mapDiv.style.height = isMobile ? '100%' : '400px';
var map = new google.maps.Map(mapDiv, {
center: new google.maps.LatLng(35.196111, -79.464167),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(document.getElementById('googft-legend-open'));
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(document.getElementById('googft-legend'));
layer = new google.maps.FusionTablesLayer({
map: map,
heatmap: { enabled: false },
query: {
select: "col4\x3e\x3e0",
from: "1ohK_Kmh7JbNZH1nC7NM-1MjhVf8OBzCJrxmbC0tq",
where: ""
},
options: {
styleId: 2,
templateId: 2
}
});
// This is the only section I added myself from the example page
layer.enableMapTips({
select: "'County Name'", // list of columns to query, typially need only one column.
from: "1ohK_Kmh7JbNZH1nC7NM-1MjhVf8OBzCJrxmbC0tq", // fusion table name
geometryColumn: 'gemoetry', // geometry column name
suppressMapTips: false, // optional, whether to show map tips. default false
delay: 200, // milliseconds mouse pause before send a server query. default 300.
tolerance: 8 // tolerance in pixel around mouse. default is 6.
});
//listen to events if desired.
google.maps.event.addListener(layer, 'mouseover', function(fEvent) {
var row = fEvent.row;
myHtml = 'mouseover:<br/>';
for (var x in row) {
if (row.hasOwnProperty(x)) {
myHtml += '<b>' + x + "</b>:" + row[x].value + "<br/>";
}
}
document.getElementById('info').innerHTML = myHtml;
});
google.maps.event.addListener(layer, 'mouseout', function(fevt) {
document.getElementById('info').innerHTML = '';
});
// Section I added myself ends here
if (isMobile) {
var legend = document.getElementById('googft-legend');
var legendOpenButton = document.getElementById('googft-legend-open');
var legendCloseButton = document.getElementById('googft-legend-close');
legend.style.display = 'none';
legendOpenButton.style.display = 'block';
legendCloseButton.style.display = 'block';
legendOpenButton.onclick = function() {
legend.style.display = 'block';
legendOpenButton.style.display = 'none';
}
legendCloseButton.onclick = function() {
legend.style.display = 'none';
legendOpenButton.style.display = 'block';
}
}
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
You need to include your apiConsoleKey valid for the domain your page is on, like the example at:
http://gmaps-utility-gis.googlecode.com/svn/trunk/fusiontips/examples/fusiontips.html
// authentication required, either API key or OAuth 2.0 token
// replace with a key valid for your domain
var apiConsoleKey = "AIzaSyA47jXARydzK61yX18t4oPpy6xUZDBukiY"; // valid for this question on stackoverflow.com, http://stac
// var apiConsoleKey = "AIzaSyAfravxKsLG5RItI93Dyh3Nya8Dg7vfYsk"; // valid for gmaps-utility-gis.googlecode.com domain only.
// var apiConsoleKey = "AIzaSyCxitB5jQcw7weQdg9MqBRfxr6mj81wT7I"; // valid for geocodezip.com
var map, layer;
function loadPoint() {
if (layer != null) {
layer.setMap(null);
google.maps.event.clearInstanceListeners(layer);
}
// original numeric ID 297050; Fusion Tables API v1.0 requires encrypted IDs.
var tableid = '15UY2pgiz8sRkq37p2TaJd64U7M_2HDVqHT3Quw';
layer = new google.maps.FusionTablesLayer({
query: {
select: 'Address',
from: tableid
},
map: map
});
layer.enableMapTips({
// authentication required, either API key or OAuth 2.0 token
key: apiConsoleKey, // replace with a key valid for your domain.
select: "'Store Name','Address'", // list of columns to query, typially need only one column.
from: tableid, // fusion table name
geometryColumn: 'Address', // geometry column name
suppressMapTips: false, // optional, whether to show map tips. default false
delay: 200, // milliseconds mouse pause before send a server query. default 300.
tolerance: 8 // tolerance in pixel around mouse. default is 6.
});
map.setCenter(new google.maps.LatLng(37.4, -122.1));
map.setZoom(10);
addListeners();
google.maps.event.addListener(layer, 'click', function(me) {
me.infoWindowHtml = me.infoWindowHtml + "<a href='javascript:void'>Test</a>";
});
}
function loadLine() {
if (layer != null) {
layer.setMap(null);
google.maps.event.clearInstanceListeners(layer);
}
// original numeric ID 296374; Fusion Tables API v1.0 requires encrypted IDs.
var tableid = '1xo_sVz4108NNejzUCGp_2nJIoOltKi467LYbHg';
layer = new google.maps.FusionTablesLayer({
query: {
select: 'geometry',
from: tableid
},
map: map
});
layer.enableMapTips({
// authentication required, either API key or OAuth 2.0 token
key: apiConsoleKey, // replace with a key valid for your domain.
select: "description", // list of columns to query, typially need only one column.
from: tableid, // fusion table name
geometryColumn: 'geometry', // geometry column name
suppressMapTips: false, // optional, whether to show map tips. default false
delay: 200, // milliseconds mouse pause before send a server query. default 300.
tolerance: 4 // tolerance in pixel around mouse. default is 6.
});
map.setCenter(new google.maps.LatLng(50.46, -104.6));
map.setZoom(12);
addListeners();
}
function loadPoly() {
if (layer != null) {
layer.setMap(null);
google.maps.event.clearInstanceListeners(layer);
}
// original numeric ID 1670859; Fusion Tables API v1.0 requires encrypted IDs.
var tableid = '18Vjqv451aikVXxlnGKhVEIJ0y4l18ZQ86eReE68';
layer = new google.maps.FusionTablesLayer({
query: {
select: 'geometry_simplified',
from: tableid
},
map: map
});
layer.enableMapTips({
// authentication required, either API key or OAuth 2.0 token
key: apiConsoleKey, // replace with a key valid for your domain.
select: "'NAME'", // list of columns to query, typially need only one column.
from: tableid, // fusion table name
geometryColumn: 'geometry_simplified', // geometry column name
suppressMapTips: false, // optional, whether to show map tips. default false
delay: 100, // milliseconds mouse pause before send a server query. default 300.
tolerance: 1 // tolerance in pixel around mouse. default is 6.
});
map.setCenter(new google.maps.LatLng(38.3, -95.4));
map.setZoom(4);
addListeners();
}
function addListeners() {
google.maps.event.addListener(layer, 'mouseover', function(fEvent) {
var row = fEvent.row;
myHtml = 'mouseover:<br/>';
for (var x in row) {
if (row.hasOwnProperty(x)) {
myHtml += '<b>' + x + "</b>:" + row[x].value + "<br/>";
}
}
document.getElementById('info').innerHTML = myHtml;
});
google.maps.event.addListener(layer, 'mouseout', function(fevt) {
document.getElementById('info').innerHTML = '';
});
}
function initialize() {
map = new google.maps.Map(document.getElementById('map_canvas'), {
center: new google.maps.LatLng(37.4, -122.1),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
loadPoly();
}
google.maps.event.addDomListener(window, 'load', initialize);
body {
font-family: Arial, sans-serif;
}
body,
html {
width: 100%;
}
#map_canvas {
height: 500px;
width: 100%;
}
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script src="http://gmaps-utility-gis.googlecode.com/svn/trunk/fusiontips/src/fusiontips.js"></script>
<div>
Move mouse over a fusion table feature and pause a while (configurable, default < 0.5 sec), a map tip will display. (documentation)
</div>
<div id='map_canvas'>
</div>
<div id='info'>
</div>
A code snippet using your table and my key:
function initialize() {
google.maps.visualRefresh = true;
var isMobile = (navigator.userAgent.toLowerCase().indexOf('android') > -1) ||
(navigator.userAgent.match(/(iPod|iPhone|iPad|BlackBerry|Windows Phone|iemobile)/));
if (isMobile) {
var viewport = document.querySelector("meta[name=viewport]");
viewport.setAttribute('content', 'initial-scale=1.0, user-scalable=no');
}
var mapDiv = document.getElementById('googft-mapCanvas');
//mapDiv.style.width = isMobile ? '100%' : '1000px';
//mapDiv.style.height = isMobile ? '100%' : '400px';
var map = new google.maps.Map(mapDiv, {
center: new google.maps.LatLng(35.196111, -79.464167),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(document.getElementById('googft-legend-open'));
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(document.getElementById('googft-legend'));
layer = new google.maps.FusionTablesLayer({
map: map,
heatmap: {
enabled: false
},
query: {
select: "col4\x3e\x3e0",
from: "1ohK_Kmh7JbNZH1nC7NM-1MjhVf8OBzCJrxmbC0tq",
where: ""
},
options: {
styleId: 2,
templateId: 2
}
});
var apiConsoleKey = "AIzaSyA47jXARydzK61yX18t4oPpy6xUZDBukiY"; // valid for this question on stackoverflow.com, http://stacksnippets.net
layer.enableMapTips({
// authentication required, either API key or OAuth 2.0 token
key: apiConsoleKey, // replace with a key valid for your domain.
select: "'County Name'", // list of columns to query, typially need only one column.
from: "1ohK_Kmh7JbNZH1nC7NM-1MjhVf8OBzCJrxmbC0tq", // fusion table name
geometryColumn: 'gemoetry', // geometry column name
suppressMapTips: false, // optional, whether to show map tips. default false
delay: 200, // milliseconds mouse pause before send a server query. default 300.
tolerance: 8 // tolerance in pixel around mouse. default is 6.
});
//listen to events if desired.
google.maps.event.addListener(layer, 'mouseover', function(fEvent) {
var row = fEvent.row;
myHtml = 'mouseover:<br/>';
for (var x in row) {
if (row.hasOwnProperty(x)) {
myHtml += '<b>' + x + "</b>:" + row[x].value + "<br/>";
}
}
document.getElementById('info').innerHTML = myHtml;
});
google.maps.event.addListener(layer, 'mouseout', function(fevt) {
document.getElementById('info').innerHTML = '';
});
if (isMobile) {
var legend = document.getElementById('googft-legend');
var legendOpenButton = document.getElementById('googft-legend-open');
var legendCloseButton = document.getElementById('googft-legend-close');
legend.style.display = 'none';
legendOpenButton.style.display = 'block';
legendCloseButton.style.display = 'block';
legendOpenButton.onclick = function() {
legend.style.display = 'block';
legendOpenButton.style.display = 'none';
}
legendCloseButton.onclick = function() {
legend.style.display = 'none';
legendOpenButton.style.display = 'block';
}
}
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body {
margin: 0;
padding: 0;
font-family: Verdana, Geneva, sans-serif;
font-size: 18px;
}
#googft-mapCanvas {
min-height: 700px;
margin: 0 auto;
padding: 0;
width: 100%;
}
#media screen and (max-width: 780px) {
#googft-mapCanvas {
min-height: 400px;
}
}
#media screen and (max-width: 480px) {
#googft-mapCanvas {
min-height: 400px;
}
}
<script src="https://maps.google.com/maps/api/js?sensor=false&v=3"></script>
<script src="http://gmaps-utility-gis.googlecode.com/svn/trunk/fusiontips/src/fusiontips.js"></script>
<h1 style="text-align: center;">Counties in NC</h1>
<div id="googft-mapCanvas"></div>
<div style="width: 700px; margin: 100px auto;">
<section id="anchor-1">
<h3>Alamance County</h3>
<p><strong>Really good quote</strong>
</p>
<p>The default automatic template shows the data from the first 10 columns. Check or uncheck the box next to the column name to include it in the automatic info window.Any format applied to the data in the column will show here. For example, if a column
contains URLs to images and the format "Four line image" has been applied in the Edit > Change columns dialog, the image will be displayed in both the table and the info window.
</p>
</section>
<section id="anchor-2">
<h3>Alexander County</h3>
<p><strong>Really good quote</strong>
</p>
<p>The default automatic template shows the data from the first 10 columns. Check or uncheck the box next to the column name to include it in the automatic info window.Any format applied to the data in the column will show here. For example, if a column
contains URLs to images and the format "Four line image" has been applied in the Edit > Change columns dialog, the image will be displayed in both the table and the info window.
</p>
</section>
<section id="anchor-3">
<h3>Alleghany County</h3>
<p><strong>Really good quote</strong>
</p>
<p>The default automatic template shows the data from the first 10 columns. Check or uncheck the box next to the column name to include it in the automatic info window.Any format applied to the data in the column will show here. For example, if a column
contains URLs to images and the format "Four line image" has been applied in the Edit > Change columns dialog, the image will be displayed in both the table and the info window.
</p>
</section>
<section id="anchor-4">
<h3>Anson County</h3>
<p><strong>Really good quote</strong>
</p>
<p>The default automatic template shows the data from the first 10 columns. Check or uncheck the box next to the column name to include it in the automatic info window.Any format applied to the data in the column will show here. For example, if a column
contains URLs to images and the format "Four line image" has been applied in the Edit > Change columns dialog, the image will be displayed in both the table and the info window.
</p>
</section>

Bing Maps .v7 How to reference pushpins with links outside of the map?

I have a Bing Map in which I have a set of pushpins, with InfoBoxes associated with each one. I am using v7.
I'd like have a link that is outside the map to display a particular pushpin's Infobox. How can this be done?
example code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<style type="text/css">
/* Define a style used for infoboxes */
.NSIMInfoBox
{
position: absolute;
border: solid 2px black;
background-color: White;
z-index: 1000;
padding: 5px;
width: 250px;
visibility: visible;
}
#mapDiv
{
position: relative;
top: 20;
left: 20;
width: 800px;
height: 800px;
border: solid 2px #555;
}
</style>
<script charset="UTF-8" type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0">
</script>
<script type="text/javascript" src="jquery-1.5.2.min.js"></script>
</script>
<script>
$(document).ready(function () {
getMap();
});
var pinInfobox = null;
var map;
var pin;
function getMap() {
map = new Microsoft.Maps.Map(document.getElementById("mapDiv"),
{ credentials: "apikey",
center: new Microsoft.Maps.Location(45.5, -122.5),
zoom: 10,
showScaleBar: true,
mapTypeId: Microsoft.Maps.MapTypeId.road
});
// //Multiple locations
// var polygonWithPins = new Microsoft.Maps.EntityCollection();
var loc1 = new Microsoft.Maps.Location(45.5, -122.5);
var loc2 = new Microsoft.Maps.Location(45.6, -122.5);
pin = new Microsoft.Maps.Pushpin(loc1);
//Microsoft.Maps.Events.addHandler(pin, 'click', displayEventInfo);
pin.setInfoBox(new InfoBox("<strong>Pushpin Number1!</strong>"));
map.entities.push(pin)
var pin2 = new Microsoft.Maps.Pushpin(loc2);
pin2.setInfoBox(new InfoBox("<strong>Pushpin Number 2!</strong>"));
map.entities.push(pin2)
}
function InfoBox(html) {
this.div;
this.html = html;
}
InfoBox.prototype.show = function (e) {
if (this.div == undefined) {
//Create container div
this.div = document.createElement("div");
this.div.className = "NSIMInfoBox";
this.div.innerHTML = createInfoBox(this.html);
this.div.style.display = "";
var mapDiv = document.getElementById('mapDiv');
mapDiv.appendChild(this.div);
}
var pinLocation = map.tryLocationToPixel(e.target.getLocation(), Microsoft.Maps.PixelReference.control);
this.div.style.left = pinLocation.x + "px";
this.div.style.top = pinLocation.y + "px";
this.div.style.visibility = "visible";
this.div.style.display = "block";
};
InfoBox.prototype.hide = function (e) {
if (this.div != undefined) {
this.div.style.visibility = "hidden";
}
};
//Extend pushpinclass
Microsoft.Maps.Pushpin.prototype.setInfoBox = function (infoBox) {
if (typeof this.infoBox != undefined && this.infoBox != undefined && this.infoBox != null) {
this.removeInfoBox();
}
// Add handlers for mouse events
this.mouseoverHandler = Microsoft.Maps.Events.addHandler(this, 'click',
function (e) { infoBox.show(e); }
);
this.mouseoutHander = Microsoft.Maps.Events.addHandler(this, 'mouseleave',
function (e) { infoBox.hide(e); }
);
};
// Extend the Pushpin class to remove an existing InfoBox object
Microsoft.Maps.Pushpin.prototype.removeInfoBox = function () {
this.infoBox = null;
// Remove handlers for mouse events
Microsoft.Maps.Events.removeHandler(this.mouseoverHandler);
Microsoft.Maps.Events.removeHandler(this.mouseoutHander);
}
function createInfoBox(html) {
var myHtml;
myHtml = '<div style="text-align:right; margin-right: 5px;" onclick="closeInfoBox();">x</div>' +
'<div style="padding: 5px;">' + html + '</div>';
return myHtml;
}
function closeInfoBox() {
$('.NSIMInfoBox').hide();
}
</script>
</head>
<body>
<div id="mapDiv" class="map"></div>
<span class="click">click me! - HERE I WANT TO SHOW THE FIRST PIN'S INFOBOX</span>
</body>
</html>
This is how I was able to solve this problem -
Since I pushed the pins into the EntityCollection, I was able to reference the pushpin by parsing through the collection, then calling the invoke method in order to get the result I was looking for:
Sample:
var newpin = map.entities.get(i);
Microsoft.Maps.Events.invoke(newpin, 'click', '');
I haven't tried this, but I would hope it can work. Essentially you can simulate the mouse events over a pushpin object.
First, when creating a pushpin, be sure to set a class name on the resulting by setting the typeName property on the pushpin options object. This will allow you get hold of the resulting div by using the css selector #mapDiv div..
Then you can create an event and dispatch it on the div, which will indicate to the map control that it should show the information associated with the pushpin. Since you're using jQuery, I think it would be something along the lines of (in response to the click event on your link that is outside the map control):
// assuming the typeName you used was "foo"
$('#mapDiv div.foo').trigger($.event('mousemove'));
You might have to try issuing mouseover before/instead of the mousemove. Also this is a general idea of a potential approach ... hopefully it yields in a solution.

Google maps in firefox6 zooms znd scrolls page

I have problem with Firefox6 (don't know if it also concerns earlier versions).
I want to embed Google Map on page, and when page has scrollbars (is longer than viewport) mouse wheel not only zooms map but also scrolls page. I tried to catch mousewheel event and stop propagation but this event isn catchable when cursor os over map. When cursor is over map controls (zoom control, google logo, etc) i can catch event and stop propagation.
What is more strange it not happens always. Sometimes page srolls and after few scrolls it stops and mousewheel only zooms map (as expected). Sometimes page doesn't scroll and sometimes it scrolls with zoom all the time. Can't find pattern.
Source code is simple:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>test</title>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
window.onload = function(){
var latlng = new google.maps.LatLng(52.25, 21.01);
mapOptions = {
zoom: 12,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
streetViewControl: false,
zoomControl:true,
mapTypeControl:false
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
}
</script>
</head>
<body>
<p style="height:500px;">-lot of text-</p>
<div id="map_canvas" style="width:500px; height:500px;"></div>
<p style="height:500px;">-lot of text-</p>
</body>
</html>
Your problem is also described on code.google.com, this problem is only in Firefox, but it isn't a Firefox bug:
http://code.google.com/p/gmaps-api-issues/issues/detail?id=3652
http://code.google.com/p/gmaps-api-issues/issues/detail?id=1605
Have also found out a workaround, that is not re-scrolling or re-zooming and works fine:
A new ScrollInterceptOverlay derived from google.maps.OverlayView, prepending a div on MapPanes.overlayMouseTarget:
Version with jQuery
// Ensure to have google.maps loaded:
// var gmap = new google.maps.Map($googlemap[0], mapOptions);
// Define a ScrollInterceptOverlay function
var ScrollInterceptOverlay = function (gmap) {
if (!(this instanceof ScrollInterceptOverlay)) return;
var $div;
var $mapDiv;
var initialize = function () {
$div = $('<div />').css({
position: 'absolute', top: 0, left: 0,
display: 'inline-block'
});
var div = $div[0];
if (div && div.addEventListener) {
// Internet Explorer, Opera, Google Chrome and Safari
div.addEventListener("mousewheel", mouseScrollStop);
// Firefox
div.addEventListener("DOMMouseScroll", mouseScrollStop);
div.addEventListener("MozMousePixelScroll", mouseScrollStop);
}
else if (div && div.attachEvent) { // IE before version 9
div.attachEvent("onmousewheel", mouseScrollStop);
}
this.setMap(gmap);
};
var mouseScrollStop = function (e) {
if (e && e.preventDefault) e.preventDefault();
};
this.onAdd = function () {
$div.prependTo(this.getPanes().overlayMouseTarget);
};
this.onRemove = function () {
var div = $div[0];
if (div && div.addEventListener) {
// Internet Explorer, Opera, Google Chrome and Safari
div.addEventListener("mousewheel", mouseScrollStop);
// Firefox
div.addEventListener("DOMMouseScroll", mouseScrollStop);
div.addEventListener("MozMousePixelScroll", mouseScrollStop);
}
else if (div && div.attachEvent) { // IE before version 9
div.attachEvent("onmousewheel", mouseScrollStop);
}
$div.detach();
};
this.draw = function () {
if ($mapDiv && $mapDiv.length === 1) {
$div.css({
width: $mapDiv.outerWidth(),
height: $mapDiv.outerHeight()
});
}
};
var base_setMap = this.setMap;
this.setMap = function (map) {
$mapDiv = $(map.getDiv());
base_setMap.call(this, map);
};
initialize.call(this);
};
// Setup prototype as OverlayView object
ScrollInterceptOverlay.prototype = new google.maps.OverlayView();
// Now create a new ScrollInterceptOverlay OverlayView object:
var mapScrollInterceptor = new ScrollInterceptOverlay(gmap);
This workaround is using jQuery, required for calculating outerWidth and outerHeight, but also for better reading.
Version with pure javaScript
Tested live: http://fiddle.jshell.net/fhSMM/7/
// Ensure to have google.maps loaded:
// var gmap = new google.maps.Map(googlemap, mapOptions);
// Define a ScrollInterceptOverlay class function
var ScrollInterceptOverlay = function () {
if (!(this instanceof ScrollInterceptOverlay)) return;
var div;
// private instance function
var mouseScrollStop = function (e) {
if (e && e.preventDefault) e.preventDefault();
};
// public instance function
this.onAdd = function () {
div = document.createElement('div');
div.style.display = 'inline-block';
div.style.position = 'absolute';
div.style.top = div.style.left = 0;
if (div.addEventListener) {
// Internet Explorer, Opera, Google Chrome and Safari
div.addEventListener("mousewheel", mouseScrollStop);
// Firefox
div.addEventListener("DOMMouseScroll", mouseScrollStop);
div.addEventListener("MozMousePixelScroll", mouseScrollStop);
}
else if (div.attachEvent) { // IE before version 9
div.attachEvent("onmousewheel", mouseScrollStop);
}
var pane = this.getPanes().overlayMouseTarget;
var firstChild = pane.firstChild;
if (!firstChild) {
pane.appendChild(div);
}
else {
pane.insertBefore(div, firstChild);
}
};
// public instance function
this.onRemove = function () {
if (div) {
if (div.removeEventListener) {
// Internet Explorer, Opera, Google Chrome and Safari
div.removeEventListener("mousewheel", mouseScrollStop);
// Firefox
div.removeEventListener("DOMMouseScroll", mouseScrollStop);
div.removeEventListener("MozMousePixelScroll", mouseScrollStop);
}
else if (div.detachEvent) { // IE before version 9
div.detachEvent("onmousewheel", mouseScrollStop);
}
var parent = div.parentNode;
parent.removeChild(div);
}
// do not delete div var'iable
div = undefined;
};
// public instance function
this.draw = function () {
var map = this.getMap();
if (map) {
var mapDiv = map.getDiv();
if (mapDiv) {
var rect = mapDiv.getBoundingClientRect();
div.style.width = rect.width + 'px';
div.style.height = rect.height + 'px';
}
}
};
};
// Setup prototype as OverlayView object
ScrollInterceptOverlay.prototype = new google.maps.OverlayView();
// Now create a new ScrollInterceptOverlay OverlayView object:
var mapScrollInterceptor = new ScrollInterceptOverlay();
mapScrollInterceptor.setMap(gmap);
Please visit also http://metadea.de/V/ about what (real) javaScript class functions are, and why I like jQuery :)
Works now for me.
Also in Firefox, the map is zooming on mousescroll, but no more scrolling the document.
Edit: Updated support for MozMousePixelScroll, refined jS
For now it looks like firefox bug. Will close question when bug will be fixed.
I had the same issue.
You could try to start Firefox with a brand new profile (e.g. by starting the Profile Manager - executing 'firefox -P' on windows systems - and choosing 'Create...') and see if the problem persists.
I had several old but seemingly empty user profiles lying around in the VMs I used to verify if this was a bug in FF 6 and obviously installing only the new binaries didn't help. On the other hand, creating a blank profile did, so I can only think of this being a migration glitch. If major versions of FF are going to be released on a bi-monthly basis, though, a lot of people are going to suffer from similar issues.
Why not take UI control of zooming? This works well for me.
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
</head>
<body>
<div class="canvas" style="width:600px;height:400px;"></div>
<script>
// Load event
$(function() {
var myOptions = {
zoom: 8,
center: new google.maps.LatLng(-34.397, 150.644),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map($('.canvas')[0], myOptions);
var overlay = new google.maps.OverlayView();
overlay.draw = function() {};
overlay.setMap(map);
// Only a Mozilla bug
if($.browser.mozilla) {
// Wait for the map DOM to be ready
google.maps.event.addListenerOnce(map, 'idle', function() {
$('.canvas > div > div:first-child > div').bind('DOMMouseScroll', function(e) {
// setTimeout needed otherwise the return false has no effect
setTimeout(function() {
// Calculate new center
var offset = $('.canvas').offset();
var pos = overlay.getProjection().fromContainerPixelToLatLng(new google.maps.Point(e.pageX-offset.left, e.pageY-offset.top));
// Calculate new zoom level
var zoom = map.getZoom();
if(e.detail < 0) zoom++;
else if(e.detail > 0) zoom--;
map.setCenter(pos);
map.setZoom(zoom);
}, 1);
// Stop propagation (prevent default)
return false;
});
});
}
});
</script>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
</body>
</html>

How to load vtip tooltip on a dynamically generated element?

I'm new to jQuery and trying to combine the use of a tooltip plugin and a lightbox plugin. More specifically, I am using Colorbox and vtip.
Colorbox generates a div which displays an image like this:
<div id="cboxLoadedContent" style="display: block; width: 400px; overflow: auto; height: 498px;">
<br>
<img src="image.jpg" id="cboxPhoto" style="margin: 49px auto auto; border: medium none; display: block; float: none; cursor: pointer;">
<br>
</div>
</code>
I next add class="vtip" title="This is a tip." in order to use the vtip style, but for some reason it does not work when it's a title tag on an element dynamically generated by Colorbox, but works on anything already loaded on the page.
Can anyone explain to me why this is and possibly offer some solutions to fix this problem?
If you don't want to have to re-call the function every time a new element is written to the page, I wrote an update to vtip. I rewrote the vtip function as a jQuery plugin, to be chainable, to allow custom settings, and to work with live elements. Its using a mapping of events, so it will work with jQuery 1.4.3 and up.
(function ($) {
$.fn.vtip = function (options) {
var settings = {
xOffset: -10,
yOffset: 6,
arrow: '/images/vtip_arrow.png'
};
if (options) $.extend(settings, options);
return this.live({
mouseenter: function (a) {
this.t = this.title;
this.title = "";
this.top = (a.pageY + settings.yOffset);
this.left = (a.pageX + settings.xOffset);
$("body").append('<p id="vtip"><img id="vtipArrow" />' + this.t + "</p>");
$("p#vtip #vtipArrow").attr("src", settings.arrow);
$("p#vtip").css("top", this.top + "px").css("left", this.left + "px").fadeIn("fast");
},
mouseleave: function (a) {
this.title = this.t;
$("p#vtip").fadeOut("fast").remove();
},
mousemove: function (a) {
this.top = (a.pageY + settings.yOffset);
this.left = (a.pageX + settings.xOffset);
$("p#vtip").css("top", this.top + "px").css("left", this.left + "px");
}
});
};
})(jQuery);
// You can use it with any class, I'm using the class 'vtip' below.
$(document).ready(function(){
$('.vtip').vtip();
});
// If necessary, add custom settings like so:
$('.vtip').vtip({xOffset:-10,yOffset:10,arrow:'/images/customArrow.png'});
I tried the code/re-written plugin on this page and ran into some complications... perhaps this will work better for someone and save you some time:
(function ($) {
$.fn.vtip = function (options) {
var settings = {
xOffset: -10,
yOffset: 20,
arrow: 'http://simages0.showtimesfast.com/icons2/vtip_arrow.png'
};
if (options) $.extend(settings, options);
return this.live('mouseover mouseout mousemove', function(a){
if(a.type == 'mouseover'){
this.top = (a.pageY + settings.yOffset);
this.left = (a.pageX + settings.xOffset);
$("body").append('<p id="vtip"><img id="vtipArrow" />' + this.title + "</p>");
$("p#vtip #vtipArrow").attr("src", settings.arrow);
$("p#vtip").css("top", this.top + "px").css("left", this.left + "px").fadeIn("fast");
}else if (a.type == 'mouseout'){
$("p#vtip").fadeOut("fast").remove();
}else if (a.type == 'mousemove'){
this.top = (a.pageY + settings.yOffset);
this.left = (a.pageX + settings.xOffset);
$("p#vtip").css("top", this.top + "px").css("left", this.left + "px");
}
});
};
})(jQuery);
Currently in use on http://www.showtimes.ca/ for you to see it working in action. Thanks to Steve above as you led me in the right direction for working with live events.
The clue is at the bottom of the vtip file:
jQuery(document).ready(function($){vtip();})
vtip is being called in document ready. It doesnt know about the elements you havent yet added. You need to recall the vtip function after you've added your elements.
vtip();
PS vtip hasnt been written as a plugin, otherwise you could chain it together with your other code eg
$('div').append('<a>example</a>').vtip(); //currently this wont work
You might want to contact the author and suggest the change, or find another tooltip - there are plenty around.

Resources