jQuery Mobile and Leaflet integration

Written by on April 8, 2015

jQuery Mobile and Leaflet integration

Henry A. Kissinger once told:

[quote]The absence of alternatives clears the mind marvelously.[/quote]

So why are we always looking for the opposite? Last few years Google maps became a standard in an online map industry. Unfortunately, bigger user base don’t always translate to a better service; precisely that happened to Google maps. Personally, this is not a problem for desktop computers, but a situation is not that good when viewed from the mobile perspective.

Somewhere along the way came Leaflet framework, a modern open-source JavaScript library for mobile-friendly interactive maps. It is developed by Vladimir Agafonkin with a team of dedicated contributors. Weighing just about 31 KB of JS, it has all the features most developers ever need for online maps. I will try to show you how to implement this framework into any jQuery Mobile project.

Note: If this tutorial was helpful, you need further clarification, something is not working or you have a request for another Ionic post? Furthermore, leave me a comment below if you don't like something about this blog, if something is bugging you, don't like how I'm doing stuff here. Feel free to comment below, subscribe to my blog, mail me to dragan.gaic@gmail.com. Thanks and have a nice day!

Table of Contents

[spoiler title=” Click here if you want to see solutions to other jQuery Mobile problems, sooner or later you’ll suffer from one.”]

[/spoiler]

Page preparation

Before we create our first example, we need to make some modifications to our jQuery Mobile page. For those of you who don’t know, any map implementation including Leaflet requires enough space to display a map. Usually, this is not a problem, then again this is jQuery Mobile.

Typical jQuery Mobile page consists of immediate children <div>’s with data-roles of header, content, and footer. Content div will never cover all available space, left by header and footer. We can fix it with a little bit of CSS:

.ui-content {
    position: absolute;
    top: 40px;
    right: 0;
    bottom: 40px;
    left: 0;
    padding: 0 !important;
}

Replace 40px with 0 if your page don’t have header or footer. Don’t forget to included !important with padding, it can’t be removed without this override.

This is a most important step of this tutorial, CSS definitions found in an official tutorial will not work with jQuery Mobile. Next step, viewport meta tag must be included in the head section or our HTML page:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />


One last thing, our map container should be set to 100% height:

#map {
    height: 100%;
}

Initializing the map

This is where Leaflet shines, it can be initialized during any jQuery Mobile page event, which is great. For those of you who don’t know, Google maps initialization will work only during the pageshow event. That looks non-native-like, sometimes with a lot of flickerings.

Demo

And here’s the final result:

jQuery Mobile and Leaflet integration

Note: When browser asks you for your location click Allow.

HTML:

<!DOCTYPE html>
<html>
    <head>
        <title>jQM Complex Demo</title>
        <meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
        <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; minimum-scale=1.0; user-scalable=no; target-densityDpi=device-dpi"/>
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.css" />
        <link rel="stylesheet" href="http://leafletjs.com/dist/leaflet.css" />
        <!--<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>-->
        <script src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.js"></script>
        <script src="http://leafletjs.com/dist/leaflet.js"></script>
    </head>
    <body>
        <div data-role="page" id="index">
            <div data-theme="b" data-role="header">
                <h1>Index page</h1>
            </div>
            
            <div data-role="content">
                <div id="map">1</div>
            </div>
        </div>    
    </body>
</html>

Javascript

$(document).on('pageinit', '#index', function(){  
    var map = L.map('map');
    
    L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
        maxZoom: 16,
        attribution: 'Example made by <a href="http://www.gajotres.net">Gajotres</a>'
    }).addTo(map);
    
    map.on('locationfound', onLocationFound);
    map.on('locationerror', onLocationError);
    
    map.locate({setView: true, maxZoom: 18});    
});

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);
}

CSS:

.ui-content {
    position: absolute;
    top: 40px;
    right: 0;
    bottom: 0;
    left: 0;
    padding: 0 !important;
}

#map {
    height: 100%;
}

Who Am I?

Between working as a senior Java developer in one of the largest insurance companies in the world and traveling, in my free time, I work as a professional mobile development adviser. I'm also a major jQuery Mobile supporter back at StackOverflow and a forum moderator at the official Ionic Framework forum.



Categories

7 thoughts on “jQuery Mobile and Leaflet integration”

  1. Thanks for the post. I had to change the semicolons separating the content properties in the viewport meta tag to commas.

  2. Hi.

    Using your code works great, but if I add a footer after content the footer is not in the correct position.
    Have you tried this situation?
    Thanks

    footer

  3. I’m new using leaflet and jquery. I do not understand where the javascript or css are referenced /included?
    Hope you can tell me where to look.
    Thanks

Leave a Reply