Leaflet and JQuery mobile

4,608 views
Skip to first unread message

Ardit700

unread,
Aug 13, 2012, 6:39:19 AM8/13/12
to leafl...@googlegroups.com
It seems like Leaflet and JQuery mobile do not work together. Here are the links that I am including in the html document:

<head> 
<title>Finding the best location</title> 
<meta name="viewport" content="width=device-width, initial-scale=1"> 
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.4.4/leaflet.css" />
<!--[if lte IE 8]>
    <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.4.4/leaflet.ie.css" />
<![endif]-->


</head> 


But I keep getting an odd map display with some grey tiles. Did anyone make it work?

Diego Guidi

unread,
Aug 13, 2012, 6:41:55 AM8/13/12
to leafl...@googlegroups.com
to me, to problem with leaflet + jqm.
try with a map div with fixed dimension, and see if you see things.
another suggests: create the map with trackResize: true, and call
map.invalidateSize() when you navigate to map page.

Diego Guidi
> --
>
>
>

stvgrc

unread,
Sep 21, 2012, 3:06:43 PM9/21/12
to leafl...@googlegroups.com
http://leaflet.cloudmade.com/examples/mobile.html

There are several other pieces of code that need to be called before it works on mobile. I'm just getting started too, in fact, I was about to join in on your request for support, then I saw that page about the mobile tutorial.  I'll go through that and drop in another comment if I have success.
Cheers.
stvgrc

stvgrc

unread,
Sep 21, 2012, 3:32:57 PM9/21/12
to leafl...@googlegroups.com
I got it working right away using the example from the Mobile Tutorial. Super easy. Here's the code:

<!DOCTYPE html> 
<html> 
<head> 
<title>My Page</title> 
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> 
<!--LEAFLET-->
    <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.4.4/leaflet.css" />
        <!--[if lte IE 8]>
            <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.4.4/leaflet.ie.css" />
        <![endif]-->
        
    
    <style type="text/css">
#map { min-height: 320px; height: 100%; margin: -15px;}
body {
padding: 0;
margin: 0;
}
html, body, {
height: 100%;
}
</style>
    
</head> 
<body> 

<div data-role="page">

<div data-role="header" data-position="fixed" data-tap-toggle="false" data-fullscreen="false">
<h1>My Title</h1>
</div><!-- /header -->

<div data-role="content">
    
    <div id="map"></div>
    
<script>
var map = L.map('map');
maxZoom: 18,
}).addTo(map);
function onLocationFound(e) {
var radius = e.accuracy / 2;
L.marker(e.latlng).addTo(map)
.bindPopup("You are within " + radius + " meters from this point").openPopup();
L.circle(e.latlng, radius).addTo(map);
}
function onLocationError(e) {
alert(e.message);
}
map.on('locationfound', onLocationFound);
map.on('locationerror', onLocationError);
map.locate({setView: true, maxZoom: 16});
</script>

    
</div><!-- /content -->
    
    <div data-role="footer" data-position="fixed" data-tap-toggle="false" data-fullscreen="false">
    <div data-role="navbar" data-position="fixed" data-tap-toggle="false" >
<ul>
<li><a href="#" id="PROFILE" data-icon="custom">PROFILE</a></li>
<li><a href="#" id="CONTACTS" data-icon="custom">CONTACTS</a></li>
<li><a href="#" id="TRIPS" data-icon="custom">TRIPS</a></li>
<li><a href="#" id="ACCOUNT" data-icon="custom">ACCOUNT</a></li>
</ul>
</div>
</div>

</div><!-- /page -->

</body>
</html>

scott.ca...@gmail.com

unread,
Feb 11, 2013, 4:42:24 PM2/11/13
to leafl...@googlegroups.com
But...

 it only works in limited circumstances.  Ajax page navigation with JQM seems to throw Leaflet for a loop. 

Consider the following mod to the code posted by stvgrc.

Rename the page with the map div to 'mapWindow' and add a div called 'home' with a link to mapWindow.  Now when you navigate from 'home' to 'mapWindow' the Leaflet map breaks (it only displays in a portion of the screen and the pan and zoom behaviors are broken).

Does anyone know why this is?  Anyone have a solution or workaround?


Here's the code with the changes highlighted.


<!DOCTYPE html> 
<html> 
<head> 
<title>My Page</title> 
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> 
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.1/jquery.mobile-1.1.1.min.css" />
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.1.1/jquery.mobile-1.1.1.min.js"></script>

<!--LEAFLET-->
    <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.4.4/leaflet.css" />
        <!--[if lte IE 8]>
            <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.4.4/leaflet.ie.css" />
        <![endif]-->
        
<script src="http://cdn.leafletjs.com/leaflet-0.4.4/leaflet.js"></script>
    
    <style type="text/css">
#map { min-height: 320px; height: 100%; margin: -15px;}
body {
padding: 0;
margin: 0;
}
html, body, {
height: 100%;
}

</style>
    
</head> 
<body> 

<div data-role="page" id="home">

<p><a href="#mapWindow"  data-role="button">Start! (HTML)</a></p>

</div>


<div data-role="page" id="mapWindow">

Oscar Hidalgo

unread,
Feb 11, 2013, 6:51:51 PM2/11/13
to leafl...@googlegroups.com
I have some examples on our web app ConMenu.com http://conmenu.com it is development with codeigniter + jquery mobile + leaflet

Examples with maps with jquery mobile + leaflet:

Menu of the day of restaurants on a radius (near me - location LEON SPAIN)

http://conmenu.com/establecimientos/mapa-menu/1/-5.5671/42.59873/H/CC

All restaurants on a radius

http://conmenu.com/establecimientos/mapa_directorio/1/-5.5671/42.59873

All restaurants in Spain

http://conmenu.com/establecimientos/mapa_todos

All on the 24003 Postal Code (Spain)

http://conmenu.com/establecimientos/mapa_directorio_en/codigopostal/24003/240890002201

I hope this will help you

scott.ca...@gmail.com

unread,
Feb 11, 2013, 7:10:41 PM2/11/13
to leafl...@googlegroups.com
@Oscar... I looked at the sources of a couple of your pages.  If I understand correctly, you're hosting the maps on separate pages and using data-rel="external" to load them rather than using ajax to serve them via data-rel="page".  This method works, but I'm targeting mobile devices via phonegap and would rather use the ajax functionality if possible.  

Or have I completely missed something in your examples?

-Scott

BTW...  Fantastic pages.

Nick

unread,
Feb 13, 2013, 8:04:12 AM2/13/13
to leafl...@googlegroups.com
You cannot use a height of 100% for #map . You need to set it in pixels.

Ricardo Freitas

unread,
Feb 13, 2013, 9:03:18 AM2/13/13
to leaflet-js
+1 for fantastic pages. Well done.


--
 
---
You received this message because you are subscribed to the Google Groups "Leaflet" group.
To unsubscribe from this group and stop receiving emails from it, send an email to leaflet-js+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

scott.ca...@gmail.com

unread,
Feb 13, 2013, 12:06:37 PM2/13/13
to leafl...@googlegroups.com
@Nick...  Thanks, but even if I change the map and body heights and widths in the css in the <head>, the map still gets torn up during the transition from #home to #mapWindow.

I have a workaround based on searching other forums for jquerymobile and leaflet, but I don't like it, and you'll see why.

The workaround is to do the following:

1.)  make the map a global

2.)  make a function to handle the page change...

function loadMap(){
    $mobile.changePage('#mapWindow')
    setTimeout(function(){
        map.invalidateSize();
    },500)
}

3.) have the link to #mapWindow call the  javascript function.

The cons:  First, it requires me to make the map a global.  Second, map.invalidateSize doesn't fire unless it's in the Timeout.  In other groups, it's been said that this timeout period could be 1ms, but I haven't found that to be the case in my app (we'll assume for now that that's my fault).

I would prefer to address the problem more directly.  So if anyone has run across this and resolved it, I'd love to know about it.  Since it was easy to replicate the problem by inserting the navigation into stvgrc's simple example, I thought I'd ask here.  

-Scott

Paul van Genuchten

unread,
Mar 4, 2013, 3:40:31 AM3/4/13
to leafl...@googlegroups.com
I had a similar visual challenge when i tried to use <div data-role="content" id="#map"> as map-container. The behaviour was gone when adding <div id="#map"/> to the content-container. I'm still facing a similar navigation issue though. 

Stefano C.

unread,
Mar 6, 2013, 1:14:57 PM3/6/13
to leafl...@googlegroups.com
I found this project today on github. I think it is useful to this topic:

Paul van Genuchten

unread,
Mar 8, 2013, 7:42:18 AM3/8/13
to leafl...@googlegroups.com

I got this working by adding a pageshow event with map.invalidateSize(false);
i had some troubles though, getting the events to fire...
finally found this post: http://stackoverflow.com/questions/7544023/how-to-initialize-pages-in-jquery-mobile-pageinit-not-firing
seems you'd place your bind code in the actual page-div

<div data-role="page" id="pageMap">

<script>
    $("#pageMap").on("pageshow", function(event, ui){
         map.invalidateSize(false);
    });
</script>


    <div data-role="content">
   
    <div id="map"></div>
   
    <script>
    var map = L.map('map');
    L.tileLayer('http://{s}.tile.cloudmade.com/xxx/997/256/{z}/{x}/{y}.png', {
    maxZoom: 18,
    }).addTo(map);
    map.setView([0,0],3);
    </script>
   
    </div>

Adriano Spanhol

unread,
May 23, 2013, 9:10:52 PM5/23/13
to leafl...@googlegroups.com
As it seems this is the most seen topic on problem leaflet + jquery mobile, i got answer on two steps and this might help others:

First, Paul is correct on invalidatesize, but i got it differently:

if ( map ) // if started
    {
    log("ifmap") //this may be discarted
    if($('#map_canvas').is(':visible') ) { //just security
        $('#map').height( $(window).height() ); // it will still respect your css, mine uses it up to 85%
        $('#map').width( $(window).width() ); // as well as height
        map.invalidateSize(); // here it comes
    }
    }


Second, i noticed jquerymobile included a div in the html that had no height and freak it up. I found the css tag that caused it, tried to overwrite it on css but didn't manage to succeed. So, i forced it up on JS. Here it is:

$('.ui-mobile [data-role="page"]').css("position", "relative"); 
$('.ui-mobile [data-role="dialog"]').css("position", "relative");
$('.ui-page').css("position", "relative");


Good luck dudes.

Jorge de Jesus

unread,
Oct 10, 2013, 2:53:51 PM10/10/13
to leafl...@googlegroups.com
Another solution:

Put all your map code into a function:

<script>
function initMap(){
    var tileServer = 'http://tiles.isric.org/worldmb10/{z}/{x}/{y}.png'
    var isricAttr = "<a href='http://www.isric.org'>ISRIC</a> World Soil Information"
        var centerMap = new L.LatLng(10, 20.22) //0,20.22           
        map = L.map('map' )
        L.tileLayer(tileServer, {}).addTo(map);
        map.setView([0,0],4)
    }
</script>

Then when the just call the function when the page is shown:


<div data-role="page" id="pageMap">
    <script>
    $("#pageMap").on("pageshow",function(event, ui) {
        initMap();
    });
    </script>       
        <div data-role="header" id="header1" data-position="fixed" data-theme="a"><h1>App</h1></div>
        <div data-role="content" id="pageContent"><div id="map"></div></div>
       
   
    </div> <!--  end of #pageMap -->

it works and it cleaner that some  solutions I've seen around :)


Jorge


Reply all
Reply to author
Forward
0 new messages