When we have large amount of data, it is very useful to provide an auto complete feature while searching for any particular item. This makes our item search feature more user convenient and easy to use.

In this post we will see how to use alloy auto complete list. We are going to fetch all the items first from back end and use that data in our autocomplete list component.

Following are the main steps:

Create a Liferay MVC portlet and create required entity and service layer

Create a Liferay MVC portlet and create required entity and service layer code. We have created a simple entity MovieDetails which stores name and rating of movies. Following is the service.xml file to create our entity. We are using service builder generated methods to fetch movie details from 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 back end

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 setting it in render request attribute, so that it will be available on page render. Note that doView() method is invoked every time before our jsp page is loaded.

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 jsp page

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>

Here, first we are getting the movie details from render request attribute, and parsing it to JSON format, the passing it to the source attribute of autocomplete-list. We have also used following important attributes:

  • inputNode : This indicates the input field where user inputs the value or search query.
  • resultTextLocator : This 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 based on what parameter, result should be filtered.
  • source : JSON array, which is to be considered for autocomplete list.

Following is the autocomplete list, with our movie details getting populated.

Autocomplete-list1

On entering the search text, auto complete list will be displayed.

Autocomplete-list2

On selecting the item from autocomplete-list, corresponding movie details will be displayed as shown below:

Autocomplete-list3

Summary: In this post, we learned how to use autocomplete-list in our liferay MVC portlet. We can also fetch autocomplete list dynamically by using Liferay’s serve resource method.

Note: Version used: Liferay 6.2 + Apache Tomcat 7.

Also Read: