VEMap Pan triggers VEMap.onclick - bing-maps

I'm using the Virtual Earth (or Bing!...) SDK and need to attach an event when someone clicks the map. Unfortunately panning the map also triggers the onclick event. Does anyone know of a work around?
function GetMap(){
map = new VEMap('dvMap');
map.LoadMap(new VELatLong(35.576916524038616,-80.9410858154297), 11, 'h',false);
mapIsInit = true;
map.AttachEvent('onclick', MapClick);
}
function MapClick(e){
var clickPnt = map.PixelToLatLong(new VEPixel(e.mapX,e.mapY));
Message('Map X: ' + clickPnt.Longitude + '\nMap Y: ' + clickPnt.Latitude + '\nZoom: ' + e.zoomLevel);
}

I'm encountering the same problem. It is certainly not what I would expect, a click event in my terminology implies that the distance between mouseDown and mouseUp is below a certain threshold.
Here is some code that works in my experiments:
<script type="text/javascript">
var mouseDownLocation;
var mouseClickThreshold = 5;
function init()
{
var map = new VEMap('myMap');
map.LoadMap(new VELatLong(-27.15,153),8,'r' ,false);
map.AttachEvent("onmousedown", function(e) {
var x = e.mapX;
var y = e.mapY;
mouseDownLocation = new VEPixel(x, y);
});
map.AttachEvent("onmouseup", function(e) {
var x = e.mapX;
var y = e.mapY;
if(Math.abs(mouseDownLocation.x - x) +
Math.abs(mouseDownLocation.y - y) > mouseClickThreshold) {
return;
}
pixel = new VEPixel(x, y);
var LL = map.PixelToLatLong(pixel);
document.getElementById("myMapInfo").innerHTML =
"Pixel X: " + x + " | Pixel Y: " + y +
"<br /> LatLong: " + LL +
"<br/>" + e.eventName;
});
}
</script>
The message will be displayed only if the mouse didn't move too much between the down and up events, i.e. a normal click should trigger it, a drag shouldn't.
This is using the VE API in version 6.2 and expects two divs with IDs "myMap" and "myMapInfo". It's also code that's experimental and could be improved upon, but the general approach seems ok.

It all depends on what you're trying to do. You could check for which mouse button was pressed during the onclick event handler. For example: If it was the Left Mouse Button then do nothing, else if it's the Right Mouse Button then do your logic to display a message, or plot pushpin, etc.
To clarify, only Panning the Map using the Mouse will trigger the onclick event. If you use the little arrows on the navigation dashboard, it will not trigger the onclick event.

Thanks Peter, that is working great with 6.3 as well. I'm discovering Bing maps and I'm a bit lost in the event handlers, so that helped!

Related

How to add a tooltip to a selection?

When the users selects some text, I want to be able to show a tooltip, right below the selected text?
Any ideas how can I do that?
You could add a component that creates the tooltip, such as paper-tooltip, or create one, even with css only, depends on your usecase.
Here is a W3 example of a CSS tooltip
As far as I can tell, react-draft-wysiwyg does not support arbitrary plugins in the same way that draft-js-plugins does.
Searching on NPM, the only text selection related plugin I found is draft-js-delete-selection-plugin. You could use that as a starting point, as well as look at the documentation for SelectionState.
Without any idea of what you have so far it is hard to provide more info. I have created a JS fiddle that shows a simple tool tip with an event listener that gets the selected text by element id
https://jsfiddle.net/03Lu28qb/1/
$(document).ready(function () {
const textSelectionTooltipContainer = document.createElement("div");
textSelectionTooltipContainer.setAttribute(
"id",
"textSelectionTooltipContainer"
);
textSelectionTooltipContainer.innerHTML = `<p id="textSelected">Selected! </p>`;
const bodyElement = document.getElementsByTagName("BODY")[0];
bodyElement.addEventListener("mouseup", function (e) {
var textu = document.getSelection().toString();
if (!textu.length) {
textSelectionTooltipContainer.remove();
}
});
document
.getElementById("textToSelect")
.addEventListener("mouseup", function (e) {
let textu = document.getSelection().toString();
let matchu = /\r|\n/.exec(textu);
if (textu.length && !matchu) {
let range = document.getSelection().getRangeAt(0);
rect = range.getBoundingClientRect();
scrollPosition = $(window).scrollTop();
containerTop = scrollPosition + rect.top - 50 + "px";
containerLeft = rect.left + rect.width / 2 - 50 + "px";
textSelectionTooltipContainer.style.transform =
"translate3d(" + containerLeft + "," + containerTop + "," + "0px)";
bodyElement.appendChild(textSelectionTooltipContainer);
}
});
});
If you trying to do it in react try this.
If you trying to do it in js try this.

jqplot tooltip display on touch instead of jqplotDataHighlight or higlightMouseOver or highlightMouseDown

I am using the jqplotDataHighlight option to display the tooltip on a chart on MouseOver.
$("#"+sTargetId).bind('jqplotcustomDataHighlight',
function (ev, seriesIndex, pointIndex, data) {
var chart_left = $("#"+sTargetId).offset().left,
chart_right = ($(window).width() - ($("#"+sTargetId).offset().left + $("#"+sTargetId).outerWidth())),
chart_top = $("#"+sTargetId).offset().top,
x = oPlot.axes.xaxis.u2p(data[0]), // convert x axis units to pixels
y = oPlot.axes.yaxis.u2p(data[1]);;
var tooltipData = data[1]*scale;
$('#tooltip').css({left:chart_left+x, top:chart_top+y, marginRight:chart_right});
$('#tooltip').html('<span style="font-family: Arial;font-size:'+sTooltip+';font:bold;color:#000000;">' +sXDisplay+': '+ tooltipData + '</span>');
$('#tooltip').show();
});
$("#"+sTargetId).bind('jqplotcustomDataUnhighlight',
function (ev, seriesIndex, pointIndex, data) {
$('#tooltip').empty();
$('#tooltip').hide();
});
It works fine.On iPad, i want the tooltip to be displayed on some touch event.How can i implement it?
// prop: highlightMouseOver
// True to highlight slice when moused over.
// This must be false to enable highlightMouseDown to highlight when clicking on a slice.
this.highlightMouseOver = true;
// prop: highlightMouseDown
// True to highlight when a mouse button is pressed over a slice.
// This will be disabled if highlightMouseOver is true.
this.highlightMouseDown = false;
I have observed that only the above two options are available. How can I implement it on touchstart or so?
Displaying the tooltip on doubleclick or any other event would also be helpful
Maybe you already figured this out. Here's what works for me. I am using jquerymobile, in jquery.jqplot.js version 0.9.7r635 line No: 2290 change mousemove to vmousemove. If you are using cursor: {followMouse: true} , then things should work out of the box, I have a fixed position for my tooltip, but on mousemove the top and left values did not get applied so i hardcoded the top and left for the tooltip div .jqplot-cursor-tooltip to appear in the same position as it does on click. Although its not a very good solution but I havent seen weird behavior till now. Hope this helps !

Javascript horizontal slider not working

I'm using an old version of the Slidedeck Plugin (v.1.4.5) and I have a javascript problem with one of the skins I'm using. More precisely, the horizontal slides are stitched together and I can't figure out how to fix this. I want each slide to be independent, without any content from the next or previous slide to be seen on the active slide.
You can see in the screenshot from below that the middle slide has visible content from the previous and next slide, which obviously I don't want to be visible.
I should mention that I have very limited knowledge of javascript / jQuery, and I suspect it's a js problem because the CSS is the same for all skins - the only variable is the script used by each skin.
You can see the slider behavior on this website and below is the full script used for the slider skin. I would appreciate any help on this. To change the slides click on each slide arrow from left or right side, or you can use the directional keys on the keyboard.
(function($){
SlideDeckSkin['fullwidth-sexy'] = function(slidedeck){
var ns = 'fullwidth-sexy';
var elems = {};
elems.slidedeck = $(slidedeck);
elems.frame = elems.slidedeck.closest('.skin-' + ns);
// Disable spines as this skin is not meant to function with spines on
elems.slidedeck.slidedeck().setOption('hideSpines', true);
elems.frame.append('PreviousNext');
elems.slidedeck.append('<div class="' + ns + '-mask left"></div><div class="' + ns + '-mask right"></div>');
elems.frame.find('.sd-' + ns + '-nav').bind('click', function(event){
event.preventDefault();
var $this = $(this);
elems.slidedeck.slidedeck().options.pauseAutoPlay = true;
if($this.hasClass('prev')){
elems.slidedeck.slidedeck().prev();
} else {
elems.slidedeck.slidedeck().next();
}
});
};
$(document).ready(function(){
$('.skin-fullwidth-sexy .slidedeck').each(function(){
if(typeof($.data(this, 'skin-fullwidth-sexy')) == 'undefined' || $.data(this, 'skin-fullwidth-sexy') == null){
$.data(this, 'skin-fullwidth-sexy', new SlideDeckSkin['fullwidth-sexy'](this));
}
});
});
})(jQuery);
The following might work, but it is hard to test without an example of what you are trying to do.
What I did is added a unique number to the ns variable (for namespace I assume.) This number is passed to the callback of the each function. (doc)
(function($){
SlideDeckSkin['fullwidth-sexy'] = function(slidedeck,uniqueName){
var ns = 'fullwidth-sexy'+uniqueName;
var elems = {};
elems.slidedeck = $(slidedeck);
elems.frame = elems.slidedeck.closest('.skin-' + ns);
// Disable spines as this skin is not meant to function with spines on
elems.slidedeck.slidedeck().setOption('hideSpines', true);
elems.frame.append('PreviousNext');
elems.slidedeck.append('<div class="' + ns + '-mask left"></div><div class="' + ns + '-mask right"></div>');
elems.frame.find('.sd-' + ns + '-nav').bind('click', function(event){
event.preventDefault();
var $this = $(this);
elems.slidedeck.slidedeck().options.pauseAutoPlay = true;
if($this.hasClass('prev')){
elems.slidedeck.slidedeck().prev();
} else {
elems.slidedeck.slidedeck().next();
}
});
};
$(document).ready(function(){
$('.skin-fullwidth-sexy .slidedeck').each(function(n){
if(typeof($.data(this, 'skin-fullwidth-sexy')) == 'undefined' || $.data(this, 'skin-fullwidth-sexy') == null){
$.data(this, 'skin-fullwidth-sexy', new SlideDeckSkin['fullwidth-sexy'+n](this,n));
}
});
});
})(jQuery);

Google Maps API v3 marker setPosition not working in Safari (sencha touch)

I am using Sencha Touch to develop a mobile version of a Bus Tracker for Boston University. The problem I a running into is that the method setPosition() for a google.maps.Marker is not rendering the position change in Safari or any Mobile browser.
The code set up is as follows:
I initialize an empty markers array
I initialize the map using Ext.Map() (sencha call)
I load data using a JSONP request every 5 seconds interval
Every time I get new data, I check if I have a marker for that bus id inside my markers array
If I don't I create a new marker and push it into my markers array
Otherwise I call setPosition with my new position on that marker in my markers array.
I then run a check to make sure the marker's position got updated to the position received from my JSON request
I have verified (I think) that the marker inside the markers array is getting the new position everytime. Also, in Chrome and Firefox, my buses move (as expected), but in safari and iPhone/Android browsers, nothing moves.
Here is the code snippet:
var markers = {};
var busesFunc = function()
{
Ext.util.JSONP.request({
url: 'http://m.cms-devl.bu.edu/rpc/bus/livebus.json.php',
callbackKey: 'callback',
params: {
},
callback: function(data) {
buses = data.ResultSet.Result;
for (var i = 0, ln = buses.length; i < ln; i++) {
var bus = buses[i];
var position = new google.maps.LatLng(bus.lat, bus.lng);
if(!markers[bus.id])
{
markers[bus.id] = new google.maps.Marker({
map: map.map,
title: 'hello',
clickable: true,
draggable: false,
position: position,
icon: "images/bg.png",
zIndex: 100
});
}
markers[bus.id].setPosition(position);
//markers[bus.id].setIcon("images/bg.png");
//markers[bus.id].setMap(map.map);
//markers[bus.id].setMap(map.map);
if(bus.lat != markers[bus.id].position.lat() || bus.lng != markers[bus.id].position.lng())
{
console.log(bus.id + " " + bus.lat + " " + bus.lng);
console.log(bus.id + " " + markers[bus.id].position.lat() + " " + markers[bus.id].position.lng());
}
}
}
});
}
setInterval(busesFunc, 5000);
You can view the sample here: http://www.bu.edu/nisdev/students/luiscarr/liveBusMobile/
And the whole javascript is called functions.js (I can't post more than one link)
[Sencha Person] markers not showing up is a known bug in the 0.93 beta release. The 0.94 release (current one) has this fixed.
Problem solved by making a unique request every interval. I figured it was a caching problem after some more debugging. So I added a timestamp parameter to the JSONP request and it was all fixed.

JavaScript Mouse position over an element (code not working)

I want to display the mouse position when its inside an element.. heres the code:
Mouse Events Example
function GetMousePositionInElement(ev, element)
{
var osx = element.offsetX;
var osy = element.offsetY;
var bottom = osy + element.height();
var x = ev.pageX - osx;
var y = bottom - ev.pageY;
return { x: x, y: y, y_fromTop: element.height() - y };
}
function handleEvent(oEvent) {
var oTextbox = document.getElementById("txt1");
var elem = document.getElementById("div1");
var xp = GetMousePositionInElement(oEvent, elem).x;
var yp = GetMousePositionInElement(oEvent, elem).y;
oTextbox.value += "\n x = " + xp + "y= " + yp;
}
Use your mouse to click and double click the red square.
div style="width: 100px; height: 100px; background-color: red"
onmouseover="handleEvent(event)"
id="div1"> /div
textarea id="txt1" rows="15" cols="50"> /textarea>
There is a problem in the code. Mouse position is not displayed inside the texArea. What changes do i have to make for the code to work and work correctly? (of-cource not all of the code is displayed and i removed some of the < and > inoder to show you some parts of the code that are not displayed otherwise but the code syntax is correct, thats not the problem)
Thank you.
var osy = element.offsetY;
There's no such property as offsetY. You may be thinking of offsetTop. However note the offsetLeft/​Top values are relative to the offsetParent not the page. If you want page-relative co-ordinates you would need to loop through offsetParents, or, since you seem to be including jQuery, call its offset function that does just that:
var offset= $(element).offset();
var osx= offset[0], osy= offset[1];
var bottom = osy + element.height();
element is a DOM HTMLDivElement object, not a jQuery wrapper object, so it doesn't have the height() method. Either add the wrapper:
var bottom= osy+$(element).height();
or use the equivalent DOM method:
var bottom= osy+element.offsetHeight;
var y = bottom - ev.pageY;
Note pageY is not part of the DOM Events standard and also not available in IE. You can calculate it by using the standard clientY property and adjusting for the page's scrollTop. Again, jQuery does this for you, adding the Firefox pageY extension to all browsers, when you use its own methods to bind your event handler:
$('#div1').mouseover(handleEvent);
instead of the inline onmouseover=... event handler attribute.