Wrong mouse coordinates when using css zoom property - css

When I use the css zoom property, the mouse coordinates are correct on all but two elements : http://seiyria.com/bootstrap-slider/ & https://fullcalendar.io
How do we fix this problem ?
Thank you in advance for your help.

For fullcalendar.io, I found a solution on Github, it is necessary to edit two functions of the file fullcalendar.js :
function getEvX(ev) {
if (ev.pageX !== undefined) {
return ev.pageX / Number($('body').css('zoom'));
}
var touches = ev.originalEvent.touches;
if (touches) {
return touches[0].pageX / Number($('body').css('zoom'));
}
}
function getEvY(ev) {
if (ev.pageY !== undefined) {
return ev.pageY / Number($('body').css('zoom'));
}
var touches = ev.originalEvent.touches;
if (touches) {
return touches[0].pageY / Number($('body').css('zoom'));
}
}
For bootstrap slider, here's the solution :
var valeurZoom = window.getComputedStyle(document.body, null).getPropertyValue('zoom');
if (valeurZoom !== "" && valeurZoom !== 1) {
eventPosition = eventPosition / valeurZoom;
}
Hopefully it helps other people !

Related

How to show text (not icon) on map using google map data layer and geoJson file?

I am able to show marker/icons using google map data layer and geoJson file(s). But instead of icons, is it possible to show a text (at particular location on map)?
It should not be part of InfoWindow. I am looking for something like Sample
I have tried using 'title' but it's just a label shown on mouse over of icon. Please help.
gmap.addListener('zoom_changed', function () {
var gmapZoom = gmap.GetZoom();
if (gmapZoom >= 0 && gmapZoom <= 21)
{
if (bJSONLoaded === false)
{
var setDataStyle = function (feature) {
var status = feature.getProperty('status');
switch (status) {
case "Active":
return {
icon: 'http://maps.google.com/mapfiles/ms/icons/green-dot.png',
title: 'test 1'
};
case "Pending":
return {
icon: 'http://maps.google.com/mapfiles/ms/icons/orange-dot.png'
};
}
};
pendingJSON.loadGeoJson('http://url/GoogleTestPending.json');
pendingJSON.setStyle(setDataStyle);
pendingJSON.setMap(gmap);
activeJSON.loadGeoJson('http://url/GoogleTestActive.json');
activeJSON.setStyle(setDataStyle);
activeJSON.setMap(gmap);
bJSONLoaded = true;
}
else
{
if (!testJSON.getMap()) {
console.log('setting map');
pendingJSON.setMap(gmap);
activeJSON.setMap(gmap);
testJSON.setMap(gmap);
}
}
}
else
{
if (bJSONLoaded === true && testJSON.getMap() != null)
{
//remove pins
pendingJSON.setMap(null);
activeJSON.setMap(null);
testJSON.setMap(null);
}
}
});
Solved it by using OverlayView.
customEntity.prototype = new google.maps.OverlayView();
And then implemented required functions like draw, onAdd, onRemove, etc.

Fullcalendar background events

Is it possible to hide events that are inside background events so that the user cannot see it?
if yes what is the way to do it ?
var isValidEvent = function(start,end,id){
return $("#calendar").fullCalendar('clientEvents', function (event) {
return (event.rendering === "background" && id!='test' &&
(start>event.start) && (end<event.end)) ;
}).length > 0;
};
eventRender:function(event, element, view) if(isValidEvent(event.start,event.end,event.id)){
$(element).hide();
},
As of the docs, eventRender callback should either return an event OR false if the event should be hidden:
eventRender:function(event, element, view)
if(isValidEvent(event.start,event.end,event.id)){
return event;
}
else {
return false;
}
},
I haven't tested yet as I don't need it, but should work that way.
I got it like this:
eventRender:function(event, element, view){
var array= new Array();
array = $("#calendar").fullCalendar('clientEvents','test');
for(i of array){
if(event.source.url=="events.php" && moment(event.start)>=moment(i.start) && moment(event.end)<=moment(i.end)){
return false;
}
} }

Google Maps v3 - prevent API from loading Roboto font

Google adds styles to the maps container that override my styles.
I know how to fix this. But the API (v3.8/9/exp) also loads the webfont "Roboto" which I don't really need/want.
Is there any setting/option/way around this?
Can I prevent the API from adding the extra CSS?
This is the code the google-maps-API adds to the <head> of my page:
<style type="text/css">
.gm-style .gm-style-cc span,
.gm-style .gm-style-cc a,
.gm-style .gm-style-mtc div {
font-size:10px
}
</style>
<link type="text/css"
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700">
<style type="text/css">
#media print {
.gm-style .gmnoprint,
.gmnoprint {
display:none
}
}
#media screen {
.gm-style .gmnoscreen,
.gmnoscreen {
display:none
}
}
</style>
<style type="text/css">
.gm-style {
font-family: Roboto,Arial,sans-serif;
font-size: 11px;
font-weight: 400;
text-decoration: none
}
</style>
You can replace the insertBefore method before the Google script invokes it:
http://jsfiddle.net/coma/7st6d9p2/
var head = document.getElementsByTagName('head')[0];
// Save the original method
var insertBefore = head.insertBefore;
// Replace it!
head.insertBefore = function (newElement, referenceElement) {
if (newElement.href && newElement.href.indexOf('//fonts.googleapis.com/css?family=Roboto') > -1) {
console.info('Prevented Roboto from loading!');
return;
}
insertBefore.call(head, newElement, referenceElement);
};
// Check it!
new google.maps.Map(document.getElementById('map'), {
center : new google.maps.LatLng(51.508742,-0.120850),
zoom : 16,
mapTypeId : google.maps.MapTypeId.ROADMAP,
streetViewControl: false,
zoomControl : false,
panControl : false,
mapTypeControl : false
});
UPDATE 10/2017
Google changed the approach of how they inject the styles on the page. Currently they inserting an empty style element and then changing the contents of this style element with Robot font. Here is a new solution:
// Preventing the Google Maps libary from downloading an extra font
(function() {
var isRobotoStyle = function (element) {
// roboto font download
if (element.href
&& element.href.indexOf('https://fonts.googleapis.com/css?family=Roboto') === 0) {
return true;
}
// roboto style elements
if (element.tagName.toLowerCase() === 'style'
&& element.styleSheet
&& element.styleSheet.cssText
&& element.styleSheet.cssText.replace('\r\n', '').indexOf('.gm-style') === 0) {
element.styleSheet.cssText = '';
return true;
}
// roboto style elements for other browsers
if (element.tagName.toLowerCase() === 'style'
&& element.innerHTML
&& element.innerHTML.replace('\r\n', '').indexOf('.gm-style') === 0) {
element.innerHTML = '';
return true;
}
// when google tries to add empty style
if (element.tagName.toLowerCase() === 'style'
&& !element.styleSheet && !element.innerHTML) {
return true;
}
return false;
}
// we override these methods only for one particular head element
// default methods for other elements are not affected
var head = $('head')[0];
var insertBefore = head.insertBefore;
head.insertBefore = function (newElement, referenceElement) {
if (!isRobotoStyle(newElement)) {
insertBefore.call(head, newElement, referenceElement);
}
};
var appendChild = head.appendChild;
head.appendChild = function (textNode) {
if (!isRobotoStyle($(textNode)[0])) {
appendChild.call(head, textNode);
}
};
})();
ORIGINAL ANSWER
Thanks to coma for the solution! I also decided to intercept styles which override the font-family, font-size and font-weight. The complete solution for modern browsers and IE8+:
// Preventing the Google Maps libary from downloading an extra font
var head = $('head')[0];
var insertBefore = head.insertBefore;
head.insertBefore = function (newElement, referenceElement) {
// intercept font download
if (newElement.href
&& newElement.href.indexOf('https://fonts.googleapis.com/css?family=Roboto') === 0) {
return;
}
// intercept style elements for IEs
if (newElement.tagName.toLowerCase() === 'style'
&& newElement.styleSheet
&& newElement.styleSheet.cssText
&& newElement.styleSheet.cssText.replace('\r\n', '').indexOf('.gm-style') === 0) {
return;
}
// intercept style elements for other browsers
if (newElement.tagName.toLowerCase() === 'style'
&& newElement.innerHTML
&& newElement.innerHTML.replace('\r\n', '').indexOf('.gm-style') === 0) {
return;
}
insertBefore.call(head, newElement, referenceElement);
};
I found above solution to prevent websites with Google Maps from loading Roboto.
If you - like I do - use Wordpress, there might be other plugins referring to Google Fonts.
However, I struggled on some of my websites with the above code, since parts of it (1) affected also other styles to load, (2) "killed" styles, which intentionally not only contained gm-style, but other styles as well and (3) not affected other Google Fonts to load, where one or another plugin added links to fonts.googleapis.com by DOM-manipulation as well.
The below worked for me. It simply prevents other scripts from adding any tag having https://fonts.googleapis.com in it's href-attribute.
(function($) {
var isGoogleFont = function (element) {
// google font download
if (element.href
&& element.href.indexOf('https://fonts.googleapis.com') === 0) {
return true;
}
return false;
}
// we override these methods only for one particular head element
// default methods for other elements are not affected
var head = $('head')[0];
var insertBefore = head.insertBefore;
head.insertBefore = function (newElement, referenceElement) {
if (!isGoogleFont(newElement)) {
insertBefore.call(head, newElement, referenceElement);
}
};
var appendChild = head.appendChild;
head.appendChild = function (textNode) {
if (!isGoogleFont($(textNode)[0])) {
appendChild.call(head, textNode);
}
};
})(jQuery);
Unfortunately, I'm a newb and I couldn't get the other suggestions to work. So I removed all the Google fonts from the DOM. I hope it helps.
const googleFont = document.querySelector('link[rel="stylesheet"][href*="fonts.googleapis.com"]');
if (googleFont) {
googleFont.remove();
}
For TypeScript a solution would be:
const head = document.head;
const insertBefore = head.insertBefore;
head.insertBefore = <T extends Node>(
newElement: T,
referenceElement: Node
): T => {
if (
newElement instanceof Element &&
newElement?.hasAttribute('href') &&
newElement?.getAttribute('href')?.includes('fonts.googleapis')
) {
return newElement;
}
insertBefore.call(head, newElement, referenceElement);
return newElement;
};

How can I Boolean based on whether my search string is a subset of the class?

I have a Wordpress site with a long table of people and data and I need to add a search filter which shows only the people who match the typed in words. Here is the code I'm using:
$(document).ready(function() {
$('input[name=searchFilterInput]').keyup(function() {
var searchFilterVal = $('input[name=searchFilterInput]').val();
searchFilterVal = searchFilterVal.replace(/ /g, '-');
searchFilterVal = searchFilterVal.toLowerCase();
if(searchFilterVal == '') {
$('tr.hide').fadeIn('slow').removeClass('hide');
} else {
$('tr.fellows').each(function() {
if(!$(this).hasClass(searchFilterVal)) {
$(this).fadeOut('normal').addClass('hide');
} else {
$(this).fadeIn('slow').removeClass('hide');
}
});
}
});
});
This works great as long as the input exactly matches the class. I need if(!$(this).hasClass(searchFilterVal)) {
to basically say "If (this) .hasClass(if the input matches any portion of the class)"
Does that make sense? Here is the page:
http://cambridgefellows.com/directory-of-fellows/?searchFilterInput=Media
Is is the second search field - the one on the right hand side of the drop down menus.
I'm sorry if this question is not asked clearly - please let me know if I can make it more clear. Thanks!
Try this .. I've cheked it , it's working
$(document).ready(function() {
$('input[name=searchFilterInput]').keyup(function() {
var searchFilterVal = $('input[name=searchFilterInput]').val();
searchFilterVal = searchFilterVal.replace(/ /g, '-');
searchFilterVal = searchFilterVal.toLowerCase();
if(searchFilterVal == '') {
$('tr.hide').fadeIn('slow').removeClass('hide');
} else {
$('tr.fellows').each(function() {
var pattern = $(this).attr('class'); // the pattern to be matched
var match = pattern.match(searchFilterVal);//If pattern matches it returns the match
if(!match) {
$(this).fadeOut('normal').addClass('hide');
} else {
$(this).fadeIn('slow').removeClass('hide');
}
});
}
});
});

Unable to iterate thru list in autocomplete using up and down arrow key in dojo

Need help..Unable to iterate thru auto suggestions using up and down arrow keys on keyboard here is little code snippet
dojo.require("dojo.NodeList-manipulate");
dojo.require("dojo.NodeList-traverse");
dojo.ready(function () {
var div = dojo.query("#list-of-items");
console.log(dojo.byId("search").getBoundingClientRect());
dojo.connect(dojo.byId("search"), "onkeyup", function (evt) {
if (dojo.byId("search").value.trim() === "") {
dojo.forEach(div.query("li"), function (elm, i) {
dojo.style(elm, {
"display": "block"
});
});
dojo.style(dojo.query("#list-of-items")[0], {
"display": "none"
});
if(evt.keyCode == 40){
return;
}else if(evt.keyCode == 38){
return;
}
} else {
dojo.style(dojo.query("#list-of-items")[0], {
"display": "inline-block"
});
}
searchTable(this.value, evt);
});
function searchTable(inputVal, e) {
console.log(inputVal);
var list = dojo.query('#list-of-items');
dojo.forEach(list.query('li'), function (elm, i) {
var found = false;
var regExp = new RegExp(inputVal, 'i');
if (regExp.test(elm.innerText)) {
found = true;
if(i===0){
dojo.attr(elm, { className: "hlight" });
}
dojo.style(elm, {
"display": "block"
});
return false;
}
if (found == true) {
dojo.style(elm, {
"display": "block"
});
} else {
dojo.style(elm, {
"display": "none"
});
}
});
}
});
and also highlight auto suggest using this css class
.hlight{
background:#faae00;
font-weight:bold;
color:#fff;
}
Please see working Fiddle here
Thanks
The best thing to do is to keep an index that contains the highlighted value, then increment/decrease that index every time the up/down arrow is pressed.
You will also have to send that index with your searchTable() function so that it can add the .hlight class to the correct elements.
The hardest part is to correct that index when someone uses the up arrow when you're already on the first element (or the down arrow when you're on the last arrow). I solved that by adding a class .visible to the elements that are visible (in stead of just adding display: block or display: none), this way you can easily query all items that are visible.
I rewrote your code a bit, ending up with this. But still, my original question is still left, why don't you use the dijit/form/ComboBox or dijit/form/FilteringSelect? Dojo already has widgets that do this for you, you don't have to reinvent the wheel here (because it probably won't be as good).

Resources