Wednesday, December 29, 2010

Liferay (s)mashup - The Beginning


Part Two - Liferay (s)mashup - Google Maps

There are many popular web services available online. From the rich set of APIs from Google and Yahoo to social sites likeTwitter and Facebook, almost all service providers make available their services in the form of an open API. These rich APIs has given rise to new kind of applications called mashups. They are basically an integration of various web APIs from different providers put together to form new kind of applications.

In this and the next series of blogs, I will show how to integrate with some of these APIs.

To make meaningful use of these APIs, let me propose a sample application where these services can be used. Let us develop a travel planning site that helps user to plan their travel dates and location. Travelling is just not about location and date. There are other factors like weather conditions, transport availabiity, political turmoil, other events clashing with date. Questions such as 'Are any of my friends travelling on that date or to that location?', 'Do I know anyone from that location I am going to?' frequently comes up. Our site will try to resolve these questions so that a probable date and location can be zeroed on.

Features of the Application
 - Display input form for receiving the source, destination, journey date and duration.
 - Show the road route of the origin and destination in Google map
 - Show weather information of origin and destination
 - Show the event happening in origin and destination on and around the journey date
 - Show news related to origin and destination
 - Moving the marker on the Google map must also update all other information in real time like weather, events, news and  the input form.
 - More services as we go along

For the first requirement, create a new portlet. In the view.jsp file, design a basic form  for the user to fill in: Origin, Destination, Journey Date and Duration.

Code Listing

<form action="<liferay-portlet:actionURL portletConfiguration="true" />" method="post" name="<portlet:namespace />fm">
    <aui:input name="origin" label="Origin" />
    <aui:input name="destination" label="Destination" />
    <aui:input name="journeyDate" label="Journey Date" />
    <aui:input name="duration" label="Duration" suffix="(in days)" />
    <input type="button" value="Search" onclick="<portlet:namespace />postPlanDetails()" />
</form>

The journeyDate is shown as a calendar when user clicks on the input field. Define it in javascript as:

AUI().ready('aui-calendar', function(A) {
    var calendar1 = new A.Calendar({
        trigger : '#<portlet:namespace />journeyDate',
        dateFormat : '%d/%m/%Y',
        setValue : true,
        selectMultipleDates : true,
        on : {
            select : function(event) {
                var normal = event.date.normal;
                var detailed = event.date.detailed;
                var formatted = event.date.formatted;
            }
        }
}).render();

A.on('mousedown', function() {
    A.CalendarManager.hideAll();
}, document);

});

The postPlanDetails() javascript function is defined as follows:

function <portlet:namespace />postPlanDetails() {
    var origin = document.<portlet:namespace />fm.<portlet:namespace />origin.value;
    var dest = document.<portlet:namespace />fm.<portlet:namespace />destination.value;
    var journeyDate = document.<portlet:namespace />fm.<portlet:namespace />journeyDate.value;
    var duration = document.<portlet:namespace />fm.<portlet:namespace />duration.value;

    Liferay.fire('planTravel', {
        origin : origin,
        destination : dest,
        journeyDate : journeyDate,
        duration : duration
    });

}

The code in bold above functions publishes the 4 parameters as an event using Liferay client side Inter Portlet Communication. For more details on IPC, see Portlet to Portlet Communication.

This portlet also receives the 'directionsChanged' event from the Google Maps portlet. We will discuss this in the next blog.

Liferay.on('directionsChanged',
    function(event) {
        document.<portlet:namespace />fm.<portlet:namespace />origin.value = event.origin;
        document.<portlet:namespace />fm.<portlet:namespace />destination.value = event.destination;
});

5 comments:

  1. Nice to see how the client side IPC is handled in LF6. Good work! What do you think about a JSP-less approach and pure JS+HTMl+CSS thing? In your example, it seems like you could replace with some LF AlloyUI JS script calls and get rid of the JSP - I'am just think loud ; )

    ReplyDelete
  2. @mcahornsirup
    I myself pretty much do not like using JSP. With JSF2 coming of age and looking viable now, I will come up with a pure JSF2 solution. That should be the way forward.

    ReplyDelete
  3. Hey.Realy nice entry. Im trying exactly that since days but having problems with the trigger atribute. It isn't working yet, also with your example in Liferay 6.0.6. I copied in an blank portlet.

    I guess it is a problem with the portlet namespace. Calendar is alway shown on top of the Liferay Page.

    But this post shows me, that I'm not a complete fool.

    ReplyDelete
  4. Hi, I am getting same issue, it is showing calendar's on top of page? do someone has a solution

    ReplyDelete
  5. hi firends can u plz post an example on IPC and hook in liferay.

    ReplyDelete