AUI Ajax in liferay portlet

Liferay supports Ajax with it’s build in Javascript library called Alloy UI. You can make AUI Ajax call from your portlet JSP to send request to your portlet and can show the result on page.

What is Ajax?

We all know it. Ajax = Asynchronous JavaScript and XML. It’s a technique to asynchronously send/retrieve data to update a small portion of a page without web page refresh. You refer to this link to know more about Ajax.

AUI Ajax call in Liferay Portlet

 

AUI Ajax in Liferay Portlet

Many times you need to make an ajax call to update portlet content. Portlets are responsible for producing a small portion of the whole page. Because of this reason, making an ajax call in portlet is slightly different than the normal java/j2ee application.

The most common use of ajax in Liferay portlet is to call resourceURL in Ajax. Liferay (till version 6.2) ships with a javascript framework called AUI (AlloyUI). Starting from Liferay 7, it uses JQuery (instead of AUI). In this article, you will see how to make AUI ajax call in Liferay portlet.

It’s easy to understand Liferay MVC portlet, so I start with it. Create Liferay MVC portlet with project name ‘ajax-test‘ and ‘-portlet‘ will be appended by Liferay IDE. Portlet class I created is com.opensource.tech.blog.portlet.TestAjaxPortlet. The project structure should look like the below screenshot.

Ajax_In_Portlet_PS

I am going to demonstrate how to make resource URL call in AUI ajax. You can refer to my blog to understand how to create resourceURL and how it works. Add following code in portlet class – TestAjaxPortlet.java

package com.opensource.techblog.portlet;

import java.io.IOException;
import java.io.PrintWriter;
import javax.portlet.PortletException;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import com.liferay.util.bridges.mvc.MVCPortlet;

public class TestAjaxPortlet extends MVCPortlet {

private static Log _log = LogFactoryUtil.getLog(TestAjaxPortlet.class.getName());
    @Override
    public void serveResource(ResourceRequest resourceRequest,
            ResourceResponse resourceResponse) throws IOException,
            PortletException {
        
        resourceResponse.setContentType("text/html");
        PrintWriter out = resourceResponse.getWriter();
        out.println("AUI Ajax call is performed");
        out.flush();
        super.serveResource(resourceRequest, resourceResponse);
    }
}

Explanation 

  • I am simply overriding serveResource method. In this method, I am simply passing HTML content to response.

Add the following code in the view.jsp.

<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>

<portlet:defineObjects />

<portlet:resourceURL var="testAjaxResourceUrl"></portlet:resourceURL>

<a href="#" onclick="ajaxCall()">resourceURL in Ajax</a>

<script type="text/javascript">
function ajaxCall(){
    AUI().use('aui-io-request', function(A){
        A.io.request('${testAjaxResourceUrl}', {
               method: 'post',
               data: {
            	   <portlet:namespace />sampleParam: 'value2',
               },
               on: {
                   	success: function() {
                        alert(this.get('responseData'));
                    }
              }
        });
    });
}
</script>

Explanation (little theory about AUI Ajax)

  • In this JSP, the resource URL is called in ajax. However, you can also call the action URL or render URL in ajax.
  • portlet:resourceURL is a tag to construct a resource URL. var attribute of this tag holds the generated resource URL.
  • I have created a javascript function called ajaxCall() in which I am making ajax call.
  • Liferay (version 6.1 & 6.2) ships with a javascript framework called AUI (AlloyUI). Starting from Liferay 7, it uses JQuery out of the box.
  • I used AUI to make an ajax call. AUI is a modular framework. To use the specific functionality, you need to register appropriate modules. For AUI Ajax, you need to register the aui-io-request module.
  • AUI().use is used to register modules.
    • The first parameter of AUI().use should be comma-separated names of modules you want to register.
    • The second parameter is a function in which you can write your code. (function(A){…})
  • Actual AUI ajax call is made by A.io.request call. It takes the following parameters
    • the first parameter is url. I have pass resourceURL created by portlet:resourceURL tag (${testAjaxResourceUrl}).
    • The second parameter is a set of configuration settings like
      • method (Post or Get)
      • data (any additional parameter if you would like to pass). Make sure you pass portlet namespace before each parameter, which is mandatory starting from Liferay 6.2.
      • on: used to define various call back function. I have defined success, which will be called on the success of the AUI ajax call. There are other call back functions like failure, end, completed, etc.
      • in the success call back function, I am simply showing the result in JS alert.
        • this.get(‘responseData’) will give you ajax call output. In our case, it’s the output generated in the serveResource method.
  • To execute AUI ajax call, I am calling ajaxCall javascript function with the link’s onclick event.

Save portlet class, view.jsp, deploy the portlet, place it on some page, click on the link, and see what output is.

Submit HTML form with AUI  Ajax

In case if you wish to pass the Html form with aui ajax, you need to change the view.jsp code as per the below snippet.

<form id="testAjaxForm" action="">
    <input type="text" name="<portlet:namespace />param2">
    <input type="button" value="Submit" onclick="ajaxCall()">
</form>

<script type="text/javascript">
function ajaxCall(){
    AUI().use('aui-io-request', function(A){
        A.io.request('${testAjaxResourceUrl}', {
               method: 'post',
               data: {
            	   <portlet:namespace />sampleParam: 'value2',
               },
               form:{
            	   id:'testAjaxForm'
               },
               on: {
                   	success: function() {
                        alert(this.get('responseData'));
                   }
              }
        });
    });
}
</script>

Explanation

  • I have created one Html form with one text box and one button. Please note that for the Input element in this form, I have passed the portlet namespace(portlet:namespace). Without this, Liferay (starting with version 6.2) will not allow to read them in the portlet.
  • I have bind ajaxCall() function on click event of the button in Html form.
  • To pass Html form with aui ajax, I have used the form attribute of A.io.request object. In the form attribute, you need to pass the id of the form you want to submit with aui ajax.
  • Rest all are same. You can still pass an additional parameter with a data attribute.

Additional Attributes of A.io.request object

You can see the full details about the attribute of the A.io.request object from the below screenshot.

Attributes in A.io.request

A_io_request_attrs

You can observe that we have used a few attributes like uri, data, form, method, etc. Let’s see how to read the form data in your portlet. you can read each input element with a separate request.getParameter() call. Update your portlet call as per the below snippet.

package com.opensource.techblog.portlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.portlet.PortletException;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;

import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.util.bridges.mvc.MVCPortlet;

public class TestAjaxPortlet extends MVCPortlet {

    private static Log _log = LogFactoryUtil.getLog(TestAjaxPortlet.class.getName());
    
    @Override
    public void serveResource(ResourceRequest resourceRequest,
            ResourceResponse resourceResponse) throws IOException,
            PortletException {
        
        String param = ParamUtil.get(resourceRequest, "param2", StringPool.BLANK);
        
        _log.info("Parameter is ==>" + param);
        
        resourceResponse.setContentType("text/html");
        PrintWriter out = resourceResponse.getWriter();
        out.print("You have entered ==>"+param);
        _log.info("Ajax call is performed");
        out.flush();
        super.serveResource(resourceRequest, resourceResponse);
    }
}

Explanation

  • I am reading the request (form) parameter by ParamUtil.get. Alternatively, you can read them by resourceRequest.getParameter, but ParamUtil.get provides additional functionality.
  • In response, I am writing the value of the request parameter. You can place logs wherever require.

Save the view.jsp and portlet class and build the portlet, and refresh the page. This time you will see there is one text box with a button. Add some value and click on the submit button. Whatever text you added in the textbox will be reached to portlet’s serveResource method, where you pass it in response. Finally, it’s visible in JS alert as per the below screenshot.

Ajax_output

You can observe the logs to make sure it calls the serveResource() method.

Additional methods of A.io.request object

A_io_request_methods

A.io.request object also supports various methods (as per the above list). What you have seen so far is setting attribute values while creating the instance of A.io.request.

AUI allows you to create the instance of A.io.request and then, later on, set the values of attributes with the set method. Let’s see how to do that.

If you wish to just create the object of A.io.request, then you need to write it like

<script type="text/javascript">
function ajaxCall(){
    AUI().use('aui-io-request', function(A){
        var ajaxRequest = A.io.request('${testAjaxResourceUrl}');
        
        ajaxRequest.set('form','id:<<Id of form>>');
        ajaxRequest.set('uri'.'actual URI');
        ajaxRequest.set('data'.'additional data to be passed in key:value pair');
        ajaxRequest.set('dataType','dataType');
        ajaxRequest.start();
    });
}
</script>

Explanation

  • You can create the instance of A.io.request and assign it to some javascript variable to use it later on.
  • This javascript variable (which holds the object of type A.io.request) will be used to set various attributes. For example, form, uri,data, dataType etc.
  • Here, I have set the Uri while creating an instance of A.io.request, but that is not mandatory. You can still create it without Uri and then later can set its Uri by calling the set method. (ajaxRequest.set(‘uri’,'<<ACTUAL_URI>>’).
  • The only problem here is this will start an ajax call as soon as you create the instance of A.io.request.
  • If you don’t wish to make aui ajax call as soon as you create the object of type A.io.request, you need to set its attribute ‘autoLoad‘ to false while creating it. Later set its other attribute.
  • Finally you need to call start() method to start aui ajax call(ajaxRequest.start()).
  • autoLoad can be set to false as per the below snippet.
<script type="text/javascript">
function ajaxCall(){
    AUI().use('aui-io-request', function(A){
        var ajaxRequest = A.io.request('${testAjaxResourceUrl}',
                          {autoLoad:false});
      })// End of AUI.use 
   } // End of ajaxCall function.
</script>

Summing UP

  • Liferay supports aui ajax call with its inbuilt javascript library – AUI.
  • aui-io-request is the module that provides support for AUI ajax in Liferay.
  • The object of A.io.request is used to make AUI Ajax call in Liferay.
  • Starting with Liferay 7, making an ajax call is very straight forward because it uses JQuery out of the box.

Download Portlet Source – (version Liferay 6.2)

Recommended For You

About the Author: Nilang

Nilang Patel is a technology evangelist who loves to spread knowledge and helping people in all possible ways. He is an author of two technical books - Java 9 Dependency and Spring 5.0 Projects.

4 Comments to “AUI Ajax in liferay portlet”

  1. Hello NiLang,

    Thank you very much for this post, I followed your guide and used it for my application, but I have a question, please give me a suggestion.

    I am using liferay 7, I want to split javascript code into 1 dependent file, I follow the guide by liferay but still not success, can you guide me how to do that?

    followed guide:
    https://dev.liferay.com/fr/develop/tutorials/-/knowledge_base/7-0/using-external-libraries?_ga=2.185018858.2144798864.1505634898-1750868252.1500468673

    Thank you and best regards,
    Hung Tran

    1. Hello Hund Tran,

      Gald to know that you are getting help from my blog.. However this topic is also new for me. I will try to look into it and let you know if found any useful. Requesting if you find any solution please do post here.

      Regards
      Nilang

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.