AUI autocomplete List – Liferay 6.2

The Autocomplete feature implementation for searching a large amount of data gives a user-friendly experience. Autocomplete feature makes our item search feature more user convenient and easy to use. The Alloy UI(AUI) provides the autocomplete feature, and we can use this component in our Liferay application development.

In this article, we will learn how to implement the autocomplete feature of the alloy(AUI) in the Liferay portal.

We will fetch all the items first from the backend and use that data in our autocomplete list component.

Version details: Liferay 6.2

Create a Liferay MVC portlet and add entity and service layer

Create a Liferay MVC portlet and create the required entity and service layer code.

We have created a simple entity class, MovieDetails which stores names and ratings of movies. Following is the service.xml file to create our entity.

We are using the service builder generated methods to fetch movie details from the database.

<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 6.2.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_6_2_0.dtd">
<service-builder package-path="com.asb">
 <author>ASB</author> 
 <namespace>ASB</namespace>
 <entity name="MovieDetail" local-service="true" remote-service="false" table="MovieDetails"> 
<!-- PK fields --> 
<column name="movie_Id" type="long" primary="true" /> 
<column name="name" type="String" /> 
<column name="rating" type="int" /> 
</entity>
</service-builder>

Fetch the data from the backend

We are fetching all the movie details available in our table inside portlet’s action class. Add the following code inside the portlet action class.

Here, we are fetching the movie details and then setting them in the render request attribute. These request attributes will be available whenever the page renders.

Every time before the jsp page loads, Liferay invokes the doView() method.

package com.asb.action;package com.asb.action;
import com.asb.model.MovieDetail;
import com.asb.service.MovieDetailLocalServiceUtil;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.json.JSONArray;
import com.liferay.portal.kernel.json.JSONFactoryUtil;
import com.liferay.portal.kernel.json.JSONObject;
import com.liferay.util.bridges.mvc.MVCPortlet;
import java.io.IOException;
import java.util.List;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
public class AutoCompleteAction extends MVCPortlet { 
@Override public void doView(RenderRequest renderRequest, RenderResponse renderResponse) throws IOException, PortletException  { 
List<MovieDetail> movieList; JSONArray jsonResults = JSONFactoryUtil.createJSONArray(); 
try { 
movieList = MovieDetailLocalServiceUtil.getMovieDetails(-1, -1); 
for(MovieDetail moviedtl : movieList) { 
JSONObject movie = JSONFactoryUtil.createJSONObject(); 
movie.put("name", moviedtl.getName()); 
movie.put("rating", String.valueOf(moviedtl.getRating())); 
jsonResults.put(movie); 
} 
} 
catch (SystemException e) { 
e.printStackTrace(); 
} 
renderRequest.setAttribute("movieResults", jsonResults.toString()); 
super.doView(renderRequest, renderResponse); 
}
}

Add the AUI auto-complete list code snippet on the jsp page

The final step is to get the render request attribute on our jsp page and add the required auto-complete script, as shown below.

<%@ taglib uri="http://alloy.liferay.com/tld/aui" prefix="aui" %>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<portlet:defineObjects />
<style>
.aui ul{ 
margin: 0px !important;
}
</style>
<% 
 String movieResults = (String)renderRequest.getAttribute("movieResults");
%>
<aui:input id="searchPackMain" name="searchPackMain" label="Search Movie Details:"/><aui:button value="Submmit" onClick="getMovieDetails()"/>
<h4>Movie Details:</h4>
< div id="moviDetailsDiv" style="padding: 1%;"></div>
<aui:script>
AUI().ready('autocomplete-list','autocomplete-filters', function(A) { 
var movies = JSON.parse('<%=movieResults%>'); 
var instance = new A.AutoCompleteList({ 
    activateFirstItem: 'true', 
    inputNode: '#<portlet:namespace/>searchPackMain', 
    resultTextLocator:'name', 
    resultFilters:['phraseMatch'], 
    render: 'true', 
    source: movies, 
  });
});
function getMovieDetails() { 
  var movies = JSON.parse('<%=movieResults%>'); 
  var movieName = document.getElementById('_AutoCompleteExample_WAR_AutoCompleteExampleportlet_searchPackMain').value; 
if(movieName.trim() == "") { 
alert("Enter search text!!"); 
} 
else { for(var i=0; i<movies.length; i++) { 
   if(movies[i].name.trim() === movieName.trim()) { 
     document.getElementById("moviDetailsDiv").innerHTML = '<b>Movie Name:</b> '+movies[i].name+'<br/><br/><b>Rating :</b> '+movies[i].rating; 
   } 
 } 
}
}
</aui:script>

We first retrieve the movie details from the render request attributes and then parse them into JSON format. Then, we pass the JSON data to the source attribute of autocomplete-list.

We have also using the following attributes:

  • inputNode: Indicates the input field where user inputs the value or search query.
  • resultTextLocator: Autocomplete-list component about which field of JSON object to be considered for auto complete. In out care, it is ‘name’ of the movie.
  • resultFilters : Indicates what parameter to use for filtering the results.
  • source: JSON array, which is to consider for autocomplete list.

Following is the autocomplete list, that populates our movie details.

Autocomplete-list1

On entering the search text, the auto-complete list displays the auto suggetion.

Autocomplete-list2

On selecting the item from the autocomplete-list, the screen displays the corresponding movie details as shown below:

Autocomplete-list3

Conclusion

In this post, we learned how to use autocomplete-list in our Liferay MVC portlet.

We can also fetch autocomplete lists dynamically by using Liferay’s serve resource method.