I was able to successfully implement the Mapael map into my HTML page, and was able to configure the hover fill color to my liking via the JavaScript code.
I'm trying to change the fill color of specific individual countries.
I've worked briefly with SVGs before, and I used to open up a file with a text editor and update certain elements that way. Is there a different way to do this?
I was wondering if this is possible with Mapael?
and Where does one grab the SVG file from?
I downloaded and deploy the repository version (jQuery-Mapael-2.2.0).
See screenshot of the files and folders.
svg code file
You have to use Mapael special function/params:
$(function () {
$("yourMapElementSelector").mapael({
// Customize some areas of the map
areas: {
"US": {
attrs: {
fill: "#488402"
}
, attrsHover: {
fill: "#a4e100"
}
}
},
});
});
I am not sure how Mapael works, but normally what I would do with the SVG is add IDs to each country, something like:
<g id="france">
or
<path id="france">
Or whatever shapes you use and then just define a CSS class similar to this:
/* if the paths are inside a group */
.svgactive path {
fill: red;
}
/* if the paths are standalone */
path.svgactive {
fill: red;
}
And just toggle the class .svgactive on your specific id inside the SVG file.
My question is how does the /admin/djangocms_icon/includes/assets.html file look like? Can someone give a sample supposing I am using font awesome 5? Below are the configuration settings that I followed on Github.
Configuration
This addon provides a default template for all instances. You can provide
additional template choices by adding a DJANGOCMS_ICON_TEMPLATES
setting::
DJANGOCMS_ICON_TEMPLATES = [
('svg', 'SVG template'),
]
Web Font Icons
##############
The django CMS Icon plugin ships with Font Awesome 4 as default. This can
be changed by overriding the following setting::
DJANGOCMS_ICON_SETS = [
('fontawesome4', 'fa', 'Font Awesome 4'),
]
To use Font Awesome 5 in the above example; see the options below from the DJANGOCMS_ICON_SETSlisted.
In addition you need to load the resources for your fonts in /admin/djangocms_icon/includes/assets.html. Add this file to your project
in order for the icon picker to pick up your custom icons in the admin.
The icon picker supports numerous font libraries <http://victor-valencia.github.io/bootstrap-iconpicker/>
out of the box. You can also add multiple font sets like this::
DJANGOCMS_ICON_SETS = [
('elusiveicon', 'el', 'Elusive Icons'),
('flagicon', 'flag-icon', 'Flag Icons'),
('fontawesome4', 'fa', 'Font Awesome 4'),
('fontawesome5regular', 'far', 'Font Awesome 5 Regular'),
('fontawesome5solid', 'fas', 'Font Awesome 5 Solid'),
('fontawesome5brands', 'fab', 'Font Awesome 5 Brands'),
('fontawesome5light', 'fal', 'Font Awesome 5 Light',
'5.3.1_pro'),
('glyphicon', 'glyphicon', 'Glyphicons'),
('ionicon', 'ion', 'Ionicons Icons'),
('mapicon', 'map-icon', 'Map Icons'),
('materialdesign', 'zmdi', 'Material Design'),
('octicon', 'octicon', 'Octicons'),
('typicon', 'typcn', 'Typicons'),
('weathericon', 'wi', 'Weather Icons'),
]
I just had to figure this out myself. It depends on whether you're trying to include a preconfigured font or your own.
Including preconfigured fonts
There is an example of an assets.html provided in the official repository at djangocms_icon/templates/admin/djangocms_icon/includes/assets.html and it's in fact linking to Font Awesome 5 (5.3.1 specifically):
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU" crossorigin="anonymous">
In order to include another font:
Copy the assets.html file into your templates folder at templates/admin/djangocms_icon/includes/assets.html (it overrides the template's default),
Add another <link> referring to your (external or local) font(s) of choice,
Add the references in your settings.py's DJANGOCMS_ICON_SETS by copying the respective element(s) from the docs.
Including custom fonts
For custom fonts, it's a tad more complicated. In my case, I only had a single .ttf file with custom icons, no CSS. In this case, the assets.html looks like this:
{% load static %}
<link rel="stylesheet" href="{% static 'css/icons/my_icons.css' %}">
In my_icons.css, include the font with an #font-face-rule and add a general myicon class plus individual classes for each of the icons:
#font-face {
font-family: "My Icons";
font-weight: normal;
font-style: normal;
src: url("../../fonts/MyIcons.ttf") format("truetype");
}
.myicon {
font-family:"My Icons";
font-style: normal;
font-size: inherit;
}
.myicon-A:before {
content:"A";
}
.myicon-B:before {
content:"B";
}
.myicon-C:before {
content:"C";
}
...
Next, put a JSON file at static/js/my_icons.js (or wherever you want) with a list of all the icon classes:
{
"iconClass": "myicon",
"icons": ["myicon-A",
"myicon-B",
"myicon-C",
"myicon-D",
...
]
}
(To generate all possible symbols, I opened the font in MacOS's font manager, copied all of the glyphs with cmd-A/cmd-C - they are really just letters - and used that to generate the rules with a short Python script.)
Finally, in your settings.py, you load the JSON and set up the reference to your custom font:
with open('path/to/static/js/my_icons.js')) as iconfile:
MY_ICON_SET = iconfile.read()
DJANGOCMS_ICON_SETS = [
(MY_ICON_SET, # = the content of the JSON file
'myicon', # = the css class
'My Icons' # = the label in the admin interface
),
]
That should be it. Don't forget to include your custom font in your website as well (e.g. in the header of your base.html template) for the icons to show up in the content as well.
I want to create a browser extension which creates a sidebar. Chrome does not have a first-class sidebar, and so we must instead put an iframe in the page. However, this breaks on many pages due to content security policy. E.g. GitHub uses a CSP, which does not allow iframes from other sites to be embedded within it. E.g. if you try to put the capitalone.com website in an iframe on GitHub you get the following:
Refused to frame 'https://www.capitalone.com/' because it violates the following Content Security Policy directive: "frame-src 'self' render.githubusercontent.com www.youtube.com assets.braintreegateway.com".
Here's a simple browser extension to reproduce that:
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (changeInfo.status === 'complete') {
chrome.tabs.executeScript(tabId, { code: 'document.body.innerHTML=\'<iframe style=\"width:600px; height:600px\" src=\"https://www.capitalone.com/\"></iframe>\' + document.body.innerHTML;' }, function() {
console.log('Iframe injection complete');
})
}
}.bind(this));
Yet, according to Wikipedia, a browser extension should be able to inject an iframe despite any content security policy:
According to the CSP Processing Model,[20] CSP should not interfere with the operation of browser add-ons or extensions installed by the user. This feature of CSP effectively allows any add-on or extension to inject script into websites, regardless of the origin of that script, and thus be exempt from CSP policies.
Is there some other way that I should be injecting an iframe besides what I'm doing?
The inability to insert an external iframe in Chrome is a bug (crbug.com/408932).
If you want to embed an external frame in an external website, then it must be loaded in a frame that is packaged with your extension.
manifest.json
{
"name": "Embed external site",
"version": "1",
"manifest_version": 2,
"content_scripts": [{
"js": ["contentscript.js"],
"matches": ["*://*/*"],
"all_frames": true
}],
"web_accessible_resources": [
"frame.html"
]
}
Do NOT use chrome.tabs.onUpdated + chrome.tabs.executeScript if you want a content script to always be inserted in a document. Your implementation is flawed and can cause the script to be run multiple times. Instead, you should declare the content script in the manifest file.
(remove "all_frames": true if you don't want to insert the frame in every subframe.)
contentscript.js
// Avoid recursive frame insertion...
var extensionOrigin = 'chrome-extension://' + chrome.runtime.id;
if (!location.ancestorOrigins.contains(extensionOrigin)) {
var iframe = document.createElement('iframe');
// Must be declared at web_accessible_resources in manifest.json
iframe.src = chrome.runtime.getURL('frame.html');
// Some styles for a fancy sidebar
iframe.style.cssText = 'position:fixed;top:0;left:0;display:block;' +
'width:300px;height:100%;z-index:1000;';
document.body.appendChild(iframe);
}
frame.html
<style>
html, body, iframe, h2 {
margin: 0;
border: 0;
padding: 0;
display: block;
width: 100vw;
height: 100vh;
background: white;
color: black;
}
h2 {
height: 50px;
font-size: 20px;
}
iframe {
height: calc(100vh - 50px);
}
</style>
<h2>Displaying https://robwu.nl in a frame</h2>
<iframe src="https://robwu.nl/"></iframe>
It is important to observe that I loaded an https site in the frame. If you attempt to load an HTTP site in the frame, then the mixed content policy will block the frame from being loaded if one of the parent frames is an https page.
Replace https://robwu.nl/ with http://example.com/ and the frame will remain blank on https pages such as https://github.com. Simultaneously, the following message will be printed to the console.
[blocked] The page at 'https://github.com/' was loaded over HTTPS, but ran insecure content from 'http://example.com/': this content should also be loaded over HTTPS
Rob W 's answer is correct. You can follow this https://transitory.technology/browser-extensions-and-csp-headers/. I 've successfully make it work in my Chrome extension https://github.com/onmyway133/github-chat
Note that I use Chrome 59, so I can use most of ES6 features
Declare in manifest
"web_accessible_resources": [
"iframe.html",
"scripts/iframe.js"
]
Create an iframe in window.onload event
let url = decodeURIComponent(window.location.search.replace('?url=', ''))
let iframe = document.createElement('iframe')
iframe.src = url
iframe.id = 'github-chat-box-iframe-inner'
iframe.style.width = '100%'
iframe.style.height = '350px'
iframe.style.border = '0px'
window.onload = () => {
document.body.appendChild(iframe)
}
Your example should work in Chrome, but it currently does not because of a bug: https://code.google.com/p/chromium/issues/detail?id=408932. Rob W's answer contains a good work-around for the issue.
How can I add a phone number to a website that is clickable but hides the link when I'm browsing on a website that doesn't support touch.
I could use Modernizr to set it up although. I don't know how.
<p><img src="assets/images/bt_calltoaction.gif" alt="View Projects" width="306" height="60"></p>
Could you just have the code in twice? i.e...
<div class="desktoptel">0800 000 000</div>
<div class="mobiletel"><a href="tel:0800-000-000">0800-000-000</div>
Then just 'display:none;' on the relevant class depending on your browser sizes?
I was just dealing with this issue, looking up solutions, and I found this thread (and a few others). I have to confess that I couldn't get any of them to work properly. I'm sure I was doing something wrong, BUT I did figure out a cheat.
As others have pointed out, changing the CSS to hide the visible link indication (color, text-decoration, cursor) is the first and easiest step. The cheat is to define a title for the tel link.
<p>Just call us at <a class="cssclassname" href="tel:18005555555"
title="CLICK TO DIAL - Mobile Only">(800) 555-5555</a>.</p>
By doing this, not only is the visible indicator of a link disguised (via CSS - see examples from others), but if someone does hover over the link, the title will pop up and say "CLICK TO DIAL - Mobile Only". That way, not only is there a better user experience, but your client doesn't accuse you of having a broken link!
For me the easiest, yet simplest method without any new classes / setup is via css:
a{
color: #3399ff;
}
a[href^="tel"]:link,
a[href^="tel"]:visited,
a[href^="tel"]:hover {
text-decoration: none;
color: #000;
pointer-events: none;
cursor: default;
}
/* Adjust px here (1024px for tablets maybe) */
#media only screen and (max-device-width: 480px) {
a[href^="tel"]:link,
a[href^="tel"]:visited,
a[href^="tel"]:hover {
text-decoration: underline;
color: #3399ff;
pointer-events: auto;
cursor: pointer;
}
}
Html just goes like this:
(+12)3 456 7
This works for modern browsers & IE 11+. If you need to include 8 < IE < 11 add the following to your javascript, since pointer-events dont work in IE:
var msie = window.navigator.userAgent.indexOf("MSIE ");
if (msie > 0){
var Elems = [], Tags = document.querySelectorAll("a[href^='tel']");
//Nodelist to array, so we're able to manipulate the elements
for (var i = 0; i < Tags.length; i++ ) {
Elems[ i ] = Tags[ i ];
}
for(var i = 0; i < Elems.length; i++){
Elems[ i ].removeAttribute('href');
}
}
EDIT: i found another answer on another thread, that may be useful for you - SO - Answer
I recently had this same problem. This problem is all over stackoverflow and everywhere else. How do you hide 'tel:' prefix and keep it from blowing up in regular browsers. There's no good single answer.
I ended up doing it this way:
first I use metalanguage to filter browser vs mobile (like php/coldfusion/perl) based on useragent string:
regular exp match for "/Android|webOS|iPhone|iPad|BlackBerry/i",CGI.HTTP_USER_AGENT
that gives me an if/else condition for desktop browser vs phone.
Next, my href tag looks like this: <a class="tel" id='tel:8005551212' href=''>800-555-1212</a>
Use CSS to style the .tel class in desktop stylesheet so it doesn't look like a link to desktop browsers. the phone number can still be clicked but its not obvious, and it wont do anything:
/* this is in default stylesheet, styles.css: */
.tel{
text-decoration:none;
color: #000;
cursor:default;
}
/* it should be re-styled in mobile css: */
.tel{
text-decoration: underline;
color: #0000CC;
cursor:auto;
}
Finally, I do a little jquery on the mobile links. The jQuery gets the id from the a.tel class, and inserts it into the href property, which makes it clickable for phone users.
The whole thing looks like this:
<!-- get regular CSS -->
<link rel="stylesheet" href="styles/styles.css" type="text/css" media="Screen" />
<!-- get user agent in meta language. and do if/else on result.
i'm not going to write that part here, other than pseudocode: -->
if( device is mobile ) {
<!-- load mobile CSS -->
<link rel="stylesheet" href="styles/mobile.css" type="text/css" media="handheld" />
<!-- run jQuery manipulation -->
<script>
$(function(){$('a.tel').prop('href',$('a.tel').prop('id'));});
</script>
}
<p> Call us today at <a class="tel" id='tel:8005551212' href=''>800-555-1212</a>!</p>
One caveat to this approach: id's should be unique. If you have duplicate phone numbers on a page that you want to link, change the id to name, then you use jQuery to loop through them.
You could use css media queries to control when its viewed as link and when not.
#media(min-width:768px){
a[href^="tel:"] {
pointer-events: none;
}
}
anything below 768px will work as link, above that, just as text.
if you just wanted to disable the click on the mobile screens:
if(typeof window.orientation !== 'undefined'){
$('a[href^="tel:"]').on('click', function(e){
e.preventDefaults();
});
}
Hope this helps :)
I've had success with this using Modernizr, specifically the touch test. It's not a perfect solution in that it doesn't do anything to help tablets or touch-enabled laptops, but it works in most desktop browsing situations.
HTML:
Call us at: 1-800-BOLOGNA
CSS:
.no-touch a.call-us {
color: black; /* use default text color */
pointer-events: none; /* prevents click event */
cursor: text; /* use text highlight cursor*/
}
The above CSS targets links with class="call-us" on non-touch devices which covers the majority of desktops.
Note that pointer-events is supported in all modern browsers but IE only supports it in versions 11+. See the compatibility chart.
Another solution, still imperfect, would be to use Modernizr.mq along with Modernizr.touch to detect screen width and touch capability and then inject the phone link with jQuery. This solution keeps the phone link out of the source code and then only appears on touch devices smaller than a certain width (say 720px which will probably cover most phones but exclude most tablets).
Ultimately, it's up to the browser vendors to come up with a bulletproof solution here.
I found the best way. I get that this is old, but I found a very easy way of doing this.
Using this code below
888-555-5555
//This is the logic you will add to the media query
.not-active {
pointer-events: none;
cursor: default;
}
In your CSS make use of media queries.
So make a media query for all desktops
#media only screen and (min-width: 64em) {
/* add the code */
.not-active {
pointer-events: none;
cursor: default;
}
}
Now all desktop sized pages wont be able to click on it.
it seems this could be done with a simple media query for most browsers. Something like this is working like a charm for me:
<style type="text/css">
#mobil-tel {
display:none;
}
#media (max-width: 700px) {
#mobil-tel {
display:block;
}
#desktop-tel{
display:none;
}
}
</style>
and on the desktop link, leave out the 'href', on the mobile link, put in the 'href'.
Just thought I would add my two-cents worth to (what is turning out to be a rather lengthy) discussion.
I basically use the onClick event (on the link) to execute Javascript to return a boolean true or false. If the return value is true, i.e. some variable or function that tests if the device is a phone returns a value true, then the href URL is followed by the browser. If the the return value is false, then the href URL becomes, in effect, inactive. (Standard HTML behavior, way before HTML5.)
Here is what I mean:-
<html>
<head>
<title>tel markup example</title>
<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script> <!-- Does not really matter what version of jQuery you use -->
<script>
var probablyPhone = ((/iphone|android|ie|blackberry|fennec/).test(navigator.userAgent.toLowerCase()) && 'ontouchstart' in document.documentElement);
function initialize() {
if ( !probablyPhone ) {
alert ("Your device is probably not a phone");
( function( $ ) {
$( '.call' ).css ( "text-decoration", "none" );
$( '.call' ).css ( "color", "black" );
$( '.call' ).css ( "cursor", "default" );
} )( jQuery );
}
}
</script>
</head>
<body onLoad="initialize();">
Please ring (some fictitious number in Australia): +61 3 9111 2222
</body>
</html>
Note that I also added some re-formatting of the link to make it appear to the user as if it's just ordinary text.
Here is a gist I created.
Just to finish this post/ answer, credit for writing succinct JavaScipt code for detecting a phone (based on the user agent and the ontouchstart event) goes to a fellow Melbournian rgb in this stackoverflow post
Here is a simple jquery-based solution which I developed to solve this problem. See code comments for explanation.
https://jsfiddle.net/az96o8Ly/
// Use event delegation, to catch clicks on links that may be added by javascript at any time.
jQuery(document.documentElement).on('click', '[href^="tel:"]', function(e){
try{
// These user-agents probably support making calls natively.
if( /Android|webOS|iPhone|iPad|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
// Do nothing; This device probably supports making phone calls natively...
} else {
// Extract the phone number.
var phoneNumber = jQuery(this).attr('href').replace('tel:', '').trim();
// Tell the user to call it.
alert("Please call "+phoneNumber);
// Prevent the browser popup about unknown protocol tel:
e.preventDefault();
e.stopPropagation();
}
} catch(e){
console.log("Exception when catching telephone call click!", e);
}
});
My approach is similar to another approach above; there are a few considerations I take into account:
As we know, there is no good programmatic way to detect support. This is a rare case where we are forced to parse the UserAgent string.
This should be client side; there is no need for server side detection.
There are now desktop browsers that can handle tel: links; Chrome's behavior on the desktop is, at worst, to do nothing when clicked. At best, you can make a call with Google Voice.
Because doing nothing when clicked is Chrome's fallback behavior, we should use that behavior as a fallback on all browsers.
If your page takes responsibility for creating tel: links, it should take responsibility for all tel: links and disable autodetection in the browser.
With all of this in mind, I suggest first adding a meta tag to your <head>:
<meta name="format-detection" content="telephone=no"/>
Then, define a JavaScript function that parses the UserAgent and returns true if and only if we think the browser will not bring us to an error page when the link is clicked:
function hasTelSupport()
{
return /Chrome\/|Mobile( Safari)?\/|Opera M(in|ob)i\/|w(eb)?OSBrowser\/|Mobile\;|Tablet\;/.test(navigator.userAgent);
}
Then, call that function from the onclick attribute in your link:
Call Me
This will allow tel: links to be clicked on Chrome, Edge, iOS Safari, Android Browser, Blackberry, Dorothy, Firefox Mobile, IE Mobile, Opera Mini, Opera Mobile, and webOS. The links will do nothing when clicked on other devices or browsers.
Please use international format for your tel: links. In other words, the first characters should be a + and a country code.
Thanks to TattyFromMelbourne's post I am now using a pretty simple bit:
My button id="call" will make the phone call based on his "probablyphone" test function but also will scroll down to the contact info section either way giving the button a working use no matter what.
I aslo replaced the alert with an empty function, to remove the pop-up.
<a id="call" href="#contact">PHONE US</a>
$("#call").on('click', function() {
var probablyPhone = ((/iphone|android|ie|blackberry|fennec/).test(navigator.userAgent.toLowerCase()) && 'ontouchstart' in document.documentElement);
var link = "callto:15555555555";
if ( !probablyPhone ) {
window.alert = function() {};}
else{window.location.href = link;}
});
</script>
You can use css3 media queries to detect a mobile window and hide the link accordingly.
#media(max-width:640px){
.your-calling-link{
display:none;
}
}
Alternately, if you want to show the link and just disable click functionality, use jquery function:
screen.width
or
screen.innerWidth
and disable the click functionality on the link using
$('.your-link').off(click);
One way of handling this is to create two separate divs and use display:hidden.
Example:
<div class="mobile-desktop"><p>123-456-7890</p></div>
<div class="mobile-mobile">123-456-7890</div>
In your css set your mobile break points. This part is really up to you. Let's say
#media only screen (min-width: 768px){
.mobile-mobile {
display:none;
}
}
#media only screen (max-width: 767px){
.mobile-desktop{
display:none;
}
}
This should let you hide one div based on screen size. Granted 789 is just a number I picked, so pick a size you believe is mobile. You can find them online at like this site I found on Google or others like it. Lastly, this is just a quick css markup, you might have to tinker but the idea is there.
This way works without adding any more CSS.
Try replacing the a tag with something else like a span tag, but only for mobile browsers of course. Benefits are that you are not cloaking this a with CSS preventing default action while keeping it still as a link. It won't be a anymore, so you won't have to worry.
I've created an example to here. Bold phone there works this way, see code below.
I took piece of code from one of the respondent to define if browser is mobile. And you have to mark these links with class="tel" or find a way to determine if the href has "tel:" in it. JQuery is also required.
// define if browser is mobile, usually I use Anthony's Hand mobile detection library, but here is simple detection for clarity
var probablyPhone = ((/iphone|android|ie|blackberry|fennec/).test(navigator.userAgent.toLowerCase()) && 'ontouchstart' in document.documentElement);
if ( !probablyPhone ) {
// find all the A with "tel:" in it, by class name
$('a.tel').each(function(){
var span = document.createElement('span');
// SPAN inherits properties of A, you can also add STYLE or TITLE or whatever
span.innerHTML = this.innerHTML;
span.className = this.className;
// replace A with SPAN
this.parentNode.insertBefore(span, this);
this.parentNode.removeChild(this);
});
}
Input this into custom css and call it a day:
a.tel { color: #FFFFFF; cursor: default; /* no hand pointer */ }
Change your color as needed.
Cheers!
I am adding the following css through javascript when mobile device is detected.
pointer-events:none
The js code is:
var a = document.getElementById("phone-number");
if (Platform.isMobile()) // my own mobile detection function
a.href = "tel:+1.212.555.1212";
else
$(a).css( "pointer-events", "none" );
In my target site, all phone link markups are in this pattern:
111-222-3333. My solution is such simple:
function setPhoneLink() {
if (screen.width > 640) {
$("a[href^='tel:']").each(function(){
$(this).replaceWith($(this).text());
});
}
}
Device-width: mobile<640; tablet >=768 and <1024; desk >=1024.
Source: http://javascriptkit.com/dhtmltutors/cssmediaqueries2.shtml
Don't use the screen size as a requirement for that.
You can use CSS media query like this:
#media (pointer: fine) { /* this is for devices using a mouse, maybe a pen */
a[href^="tel:"] { /* select only "tel:" links */
pointer-events: none; /* avoid clicks on this element */
}
}
#media (pointer: coarse) { /* this works for mobile phones */
}
More info: https://developer.mozilla.org/en-US/docs/Web/CSS/#media/pointer
#media screen {.telephone {pointer-events: none;}}