Bringing Google Maps JavaScript API V3 into Liferay Web and WAP

Liferay 6 provided integration with Google Maps JavaScript API V2. More details, AUI tags are used to integrate Google Maps JavaScript API V2. The Google Maps API lets us embed Google Maps in the web pages with JavaScript. The API provides a number of utilities for manipulating maps and adding content to the map through a variety of services, allowing us to create robust maps applications on website. The following is sample code.

<aui:script>
  var <portlet:namespace />map;
  var <portlet:namespace />geocoder;
  function <portlet:namespace />load() {...}
  ...
</aui:script>

You can also refer to view.jsp.

V3 of Google Maps JavaScript API is especially designed to be faster and more applicable to mobile devices, as well as traditional desktop browser applications. New features of V3 include,

  • Draggable directions within the V3 Maps API allowing users to modify directions and add waypoints by dragging the path on the map.
  • Create your own Custom Panoramas and display them using the V3 Maps API Street View service.

Most importantly, V2 of  Google Maps JavaScript API has been officially deprecated, refer to basics.html. Thus it is time for Liferay community to upgrade to Google Maps JavaScript API V3 LPS-13968.

This article will address how to bring Google Maps JavaScript API V3 into Liferay 6 Web and WAP - Mobile devices.

Integration Overview

Google Maps JavaScript API is more applicable to mobile devices, as well as traditional desktop browser applications. Normally, mobile devices and desktop browser applications should support HTML 5.  Here list a few browsers as examples.

Safari 5

 Chrome 7 and FireFox 3.6

 And most importantly, Google Maps JavaScript API V3 is especially designed to be faster and more applicable to mobile devices, like iPhone (iOS v2.2 - v4.0), Palm Pre (webOS v1.4.1), Android (v1.5 - v2.2), BlackBerry OS (v5.0, v6.0), especially iPad, etc.

iPhone 4

Palm Pre

Implementation

In general, you can bring Google Maps JavaScript API V3 into Liferay WEB and WAP in three steps.

  • Declare a true DOCTYPE within your web application. That is, declare the applications as HTML5 using the simple HTML5 DOCTYPE as shown below

  <!DOCTYPE html>

  • For the map to display on a web page, you must reserve a spot for it by creating a named div element and obtaining a reference to this element in the browser's document object model (DOM).

  <div id="map_canvas" style="width: 100%; height: 100%"></div>

  • Add JavaScript calls as follows

<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>

<script type="text/javascript">

  function initialize() {

    var <portlet:namespace />geocoder = new google.maps.Geocoder();

    var myLatlng = new google.maps.LatLng(-34.397, 150.644);
    var myOptions = {
      zoom: 8,
      center: myLatlng,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    }

   var <portlet:namespace />map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

   }
</script>

As you can see, JavaScript specifies the JavaScript class that represents a map is the Map class.

var <portlet:namespace />map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

Of course, you can add your JavaScript code inside the method initialize().

Results

Based on above steps, you can build a portlet called Google Maps V3 for both WEB and WAP in following steps.

  • Using HTML5 DOCTYPE in the theme (either WEB or WAP theme), like Classic theme (WEB) in Liferay 6.
  • Adding DOM <DIV> and JavaScript in view pages of the portlet Google Maps V3.

That's it. Is it so easy?

What’s next?

Google Maps JavaScript API V3 provides a lot of features like:

  • Events
  • Controls
  • Overlays
  • Services
  • Map Types

It would be nice that the portlet Google Maps V3 could merge above features in one place and, moreover, end users could customize their maps easily.

Your comments / suggestions?

Blogues
Why do you do you namespace "<portlet:namespace />" javascript local variables? Porlet namespacing is only required for global variables.

- Sampsa
Hi Sampsa, Thanks. Good point. Namespace "<portlet:namespace />" is not required for JavaScript local variables. But in the portlet Google Maps V3, it would be better to have global variables using Porlet namespace in order to avoid any potential conflicts. Do you agree?

Jonas
Hi Jonas

I agree with you that portlet namespace has to be used, but ONLY where needed ;) The svn attachment view.jsp is good code because it is dealing portlet namespace requirements, but code little bit ugly because there are too much <portlet:namespace /> pollution. To write cleaner code and avoid portlet namespace pollution you can wrap your code with closure.

Wrapping to portlet JavaScript code to closure example:

(function(window, namespace) {
var wn = window[namespace];
wn.globalvariable = "I'm global variable";
var myValue = "I'm only visible inside closure";
wn.getMyValue = function() {
return myValue;
};
})(window, "<portlet:namespace />");

This also makes good minified result. I like to see all of my portlet JavaScript logic also to separated to own JavaScript file - Liferay has excellent .js file binding to portlet support. Because of that I have written a little framework http://code.google.com/p/jquery-portlet/ - but that is another story.

Anyway, writing clean javascript portlet code could be good subject emoticon

- Sampsa
How to install an OpenXava application on Liferay......?

If i am follow the instructions given the liferay , but i am unable to integrate the liferay with openxava.

I will follow the instruction of the following links as follows

http://www.liferay.com/community/wiki/-/wiki/Main/How+to+install+an+OpenXava+application+on+Liferay

http://openxava.wikispaces.com/tomcat-liferay-setup

If any body integrate liferay with Openxava , Please Guide me the Detailed steps to integrate liferay with Openxava .
Hi Jonas,

thank you for that. But i cannot refer to view.jsp as mentioned above. Could you please provide a full Version of view.jsp because my Integrations seems to have some css z-layer issues ;-)

Markus
Hi Markus, you can find view.jsp at http://www.liferay.com/c/document_library/get_file?p_l_id=5624309&groupId=31578&folderId=6815235&name=DLFE-85603.jsp.

Note that above view.jsp is used for Google Maps JavaScript API V2 only.

Thanks
Hi Jonas,

I followed your example for Google Maps V3 integration with Liferay 6.0-EE, am unable to veiw or load the map with basic configuration, the issue am facing is that the Liferay portal gets struck and its unable to load the page further

The code of my view.jsp as follows,
<%@include file="mapInit.jsp"%>

<script type="text/javascript"
src="http://maps.google.com/maps/api/js?sensor=false"></script>


<aui:script use="aui-base">
var map;
/*
*
*/
function intitialize() {
alert("init map");
var latlng = new google.maps.LatLng(13.066202, 80.250263);
var mapOptions = {
zoom : 12,
center : latlng,
mapTypeId : google.maps.MapTypeId.ROADMAP,
mapTypeControl : true,
panControl : true
};
map = new google.maps.Map(document.getElementById("map_canvas"),
mapOptions);
}
google.load("maps", "3", {
callback : intitialize
});
</aui:script>
<div id="map_canvas"></div>

Am i missing something here ?

Thanks
Kamesh
Hi kamesh, thanks.

You should use

<script type="text/javascript">

instead of

<aui:script use="aui-base">

Hope that it helps,

Jonas
Hi Jonas,

Thanks very much for the reply, after changing that to script it did work and i finally made it to work with the following code which will be part of view.jsp,

<%@include file="mapInit.jsp"%>
<script>
var map;
function initialize() {
//alert("Intialzing the maps working ....");
var myLatlng = new google.maps.LatLng(-34.397, 150.644);
var storeMapOptions = {
zoom : 8,
center : myLatlng,
mapTypeId : google.maps.MapTypeId.ROADMAP
};

map = new google.maps.Map(document.getElementById("map_canvas"),
storeMapOptions);

}
function initLoader() {
var script = document.createElement("script");
script.src = "http://maps.google.com/maps/api/js?v=3.1&sensor=false&callback=initialize";
script.type = "text/javascript";
document.getElementsByTagName("head")[0].appendChild(script);
}
</script>
<div id="map_canvas"></div>
<script>
initLoader();
</script>

Dont know why didn't wok the previous way emoticon

I also added the following css modification to make it work, otherwise the map gets loaded and not displayed

CSS
.map-portlet #map_canvas {
height: 480px;
width: 640px;
}
You can now later this to display the size its needed to be

Another questions
1. I have is how do we contribute to the blogs ? I dont see any link to activate or register for the blog.

2. Any documentation available on usage of aui:script i have seen some wikis but really dont understand its importance and usage

Thanks.
Kamesh
Hello Kamesh.
I write my portlet the same as you. But the maps cannot be displayed.
So would you send me your sample project for me? I need it just for reference.
Hi Jonas...

I'm wondering if you can help me with this issue. I'm trying to build a portlet in LF 6.1 as a plugin liferay ide and the simplest way of use the google map api v3 didn't not work for me...i have a portlet using Liferay MVC.

In a simple jsp (and all the portlet is just this lines :S) i have:

1

2
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=my_key&sensor=false" ></script>
3
<script type="text/javascript">
4

5
AUI().ready('event', 'node', function(A){
6
    var mapOptions = {
7
            center: new google.maps.LatLng(-34.397, 150.644),
8
            zoom: 8,
9
            mapTypeId: google.maps.MapTypeId.SATELLITE
10
    };
11
    var map = new google.maps.Map(A.one("#<portlet:namespace />map"), mapOptions);
12
});
13
   
14
</script>
15
<aui:form name="fm">
16
    <aui:fieldset>
17
        <aui:layout>
18
            <div class="maps-content" id="<portlet:namespace />map"></div>
19
        </aui:layout>
20
    </aui:fieldset>
21
</aui:form>


Thanks in advance!!