Tuesday, January 21, 2014

Liferay Client Side Inter Portlet Communication Using Ajax

Objective:

Achieve inter portlet communication from client side using Ajax and Liferay Java Script.

Introduction:

Inter portlet communication is way of exchange the data between portlets in the page or portlets which reside in the other pages.

In liferay we have different ways we can achieve this one of the way is client side inter portlet communication.

Environment:

Liferay 6.2 +Tomcat 7.x+MySQL 5.1

Note:

The code will work for portal 6.2 version you can try for 6.1 too.

Download Client Side IPC portlet from following location

You can find source and war file


Portlet Screen:



Procedure for deploy portlet:

You can use war file and directly place in your portal deploy folder and test or you can also use source to deploy portlet.

Once portlet is deployed successfully you can see the portlet in sample category names as Sender Portlet and Receiver Portlet.

Usage Of Portlets:

Drag and Drop two portlet in same page and enter email address in sender portlet then click on send button as soon as you click you can see user details in receiver portlet.

Client Side Inter Portlet Communication (IPC):

Client Side Inter Portlet Communication is one of the ways in IPC   this can apply the portlet which reside in same page. Because Client side IPC will uses java script to communicate that’s why all portlet which participated in IPC need to be in same page.

Liferay already have some java script library to implement client side IPC in portlet 
development.

The following diagram show you the IPC among Portlets


Here we have two types of portlets

Sender Portlet
Receiver Portlet

Sender Portlet:

Sender portlet will fire or trigger the event means it will initiate the sending message to other portlet.

Receiver Portlet

Receiver portlet is ready to take/listen the event from sender portlet as soon as sender portlet send the message then receiver portlet reactive the messages. Here one or more receiver portlet can be for one sender portlet.

The thing is we need to bind the receiver portlet with sender event. So that it can be listen the event as soon as sender sends the message.

Note:

All portlet which participate in client side IPC should be in same page and here page refresh will not be happened.

Assumption:

Assume we have sender and receiver portlet in page and sender will get some user data from server and the data will be pass to receiver portlet.

Sender portlet get the data from server it will use the Ajax call and once it will get the data then the data will be sending to receiver portlet using Client Side IPC with help of liferay java script implementation methods.

Register event in sender portlet as follows


Java script syntax

 Liferay.fire('eventName',{
                param1:paramValue1,
                param2:paramValue2
});

Example code as follows in sender portlet view.jsp

Liferay.fire('getUserData',{
              name: Meera Prince
});
                 
                

Receive the event from Sender Portlet in receiver portlet as Follows


Java script syntax

Liferay.on('eventName',function(event) {
// write code to get the veluese that sent by sender portlet
});

Example code as follows in receiver portlet view.jsp

Liferay.on('getUserData',function(event) {
 alert('User Name:'+ event.name)
});



Implementation In development

The following are the steps to implement
  1. Create Two Liferay MVC portlets
  2. Make it <requires-namespaced-parameters/>   tag value to false in portlets
  3. Register Event in Sender Portlet
  4. Receive Event in Receive portlet

Note:

This is Client Side IPC events mechanism using java script and the portlet all are in same page.

Create Two Liferay MVC portlets

Create two Liferay MVC portlet from Liferay IDE with eclipse environment and decide Sender and Receiver portlets.

The following is more information to set up Liferay Development Environment


Make it <requires-namespaced-parameters/>   tag value to false in portlets

In liferay-portlet.xml file we need to make <requires-namespaced-parameters/>   tag value to false so that we can pass data in request using Ajax call.

This we need to make it false in spring portlet and when we use ajax as well.

If we make it false then only we can pass data to server using Ajax call.

The following is example for liferat-portlet.xml file as follows


<portlet>
<portlet-name>sender</portlet-name>
<icon>/icon.png</icon>
<instanceable>false</instanceable>
<requires-namespaced-parameters>false</requires-namespaced-parameters>
<header-portlet-css>/css/main.css</header-portlet-css>
<footer-portlet-javascript>/js/main.js</footer-portlet-javascript>
<css-class-wrapper>sender-portlet</css-class-wrapper>
</portlet>

Which portlet need Ajax interaction then we need to make it false to that portlet.

Register Event in Sender Portlet

Now we need register required even in Sender portlet so that it will send events to receiver portlets. This is complete java script implementation and we will use Liferay java script implementation.

Here we will get user information from server using jQuery Ajax call and once we get user data then we are sending to receiver portlet  using liferay java script implementation method i.e. Liferay.fire(----)

The following is example code in Sender Portlet view.jsp page

<%@page import="com.liferay.portal.theme.ThemeDisplay"%>
<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet"%>
<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>
<%@ taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %>
<%@ page import="com.liferay.portal.kernel.portlet.LiferayWindowState" %>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<portlet:defineObjects />
<liferay-theme:defineObjects />
<portlet:resourceURL var="getUserData">
</portlet:resourceURL>
<script>
$(document).on('ready',function(){
jQuery('#<portlet:namespace/>getUserByEmail').click(function(event) {
var emailAddessValue = jQuery('#<portlet:namespace/>emailAddess').val();
  $.ajax({
url:'<%=getUserData%>',
dataType: "json",
data:{emailAddess:emailAddessValue,
companyId:'<%=themeDisplay.getCompanyId()%>'
},
type: "get",
success: function(data){
Liferay.fire('getUserData', {userData:data});
},
beforeSend: function(){
//before send this method will be called
},
complete: function(){
//after completed request then this method will be called.
},
error: function(){
$('#userContent').html('<span style="color:red">Connection problems</span>');
}
});
});
});
</script>
<aui:form method="POST" action="<%=getUserData%>" >
<aui:input type="text" name="emailAddess"   id="emailAddess" label="Email Address"/>
<aui:button type="button" name="getUserByEmail" value="Send" id="getUserByEmail" />
</aui:form>

Receive Event in Receive portlet

Now we need to receive the even in receiver portlet. We already know sender send the message or event now we need to catch the message using Liferay.on(---) method.

Note:

We can have multiple receiver portlet for one sender portlet.

The following is complete code in receiver portlet view.jsp page


<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet"%>
<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>
<%@ taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %>
<portlet:defineObjects />
<style>
#userData td{
font-weight: bold;
width:200px;
border: 1px solid gary;
}
</style>
<script>
Liferay.on(
'getUserData',function(event) {
jQuery('#userInformation').empty();
jQuery('#errorInformation').empty();
if(event.userData.error!=null){
            jQuery('#errorInformation').html(event.userData.error);
}else{
var htmlString="<table id='userData'>"+
"<tr><td>User Id</td><td>"+event.userData.userId+"</td></tr>"+
"<tr><td>First Name</td><td>"+event.userData.firstName+"</td></tr>"+
"<tr><td>Last Name</td><td>"+event.userData.lastName+"</td></tr>"+
"<tr><td>Email Address</td><td>"+event.userData.emailAddress+"</td></tr>"+
"</table>";
jQuery('#userInformation').html(htmlString);
}
});
</script>
<div id="userInformation"></div>
<div id="errorInformation" style="color:red;font-weight:bold;"></div>

Important points:
  • Inter Portlet Communication (IPC) can be achieved in different ways and client side IPC is one of the way.
  • Client Side IPC is pure java script implementation so that It apply only the portlet which are in same page.
  • Liferay implemented some java script methods to implement Client Side IPC.
  • We used Ajax call to get data from server one we get the data we populated in other portlet using Client Side IPC.

Author
Liferay Top Contributor Award Winner

Popular Posts

Recent Posts

Recent Posts Widget