Tuesday, February 18, 2014

Liferay AUI Auto Complete List

Introduction:

Liferay have very rich JavaScript library that is AUI Java Script Library. This library inherited from YUI.

Liferay AUI has had one of the java script component that is Auto Complete List and this will help us to populate matching values in the input when user type something in Input box. This will help end user can see desired matching result when he look for something.

Example:

We have number of countries and when we populate in select box then user need to select one of the country for given select box options here user need to search in all options. Instead of that if user types some letter/text in text box then it will show matching results so that user can easily select appropriate option in quick time.

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 Liferay Auto Complete List Portlet from following location

You can find source and war file


Portlet Screen-1:


Portlet Screen-2:


Portlet Screen-3:


Portlet Screen-4:


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 name as Auto Complete List.

Note:

Before use this portlet please Read entire Article and Use it.

Implementation in Plugin Portlet

The thing is very simple AUI Auto Complete List need JSON array.

The following is simple AUI script for Auto Complete List

new A.AutoCompleteList(
{
allowBrowserAutocomplete: 'true',
activateFirstItem: 'true',
inputNode: '#myInputNode',
resultTextLocator: 'name',
render: 'true',
source:this.get('responseData'),
})

Important Options:

inputNode:

This is input element id where data will be populate.

Source:

This is JSON array where populated data is available

resultTextLocator:

This is search key like if JSON array have list of object then it will search based on given key nothing but matching key in object.

resultFilters:

Filter when user types something in input. This will take array of filters some of the filters are as follows.

charMatch:
           
 Returns results that contain all of the individual characters in the query, in any order (not necessarily consecutive).

phraseMatch:

 Returns results that contain the complete query as a phrase.

startsWith:

Returns results that start with the complete query as a phrase.

subWordMatch:

Returns results in which all the words of the query match either whole words or parts of words in the result. Non-word characters like whitespace and certain punctuation are ignored.

wordMatch:

 Returns results that contain all the individual words in the query, in any order (not necessarily consecutive).

Example:

 resultFilters: ['charMatch', 'wordMatch']


Note:

We need pass array of available options to AUI Auto Complete List.

We will use Ajax call get JSON data from server and populate in AUI Auto Complete List as some input.

Simple AUI Auto Complete List Example

Add following code in JSP page

<%@page import="com.liferay.portal.kernel.util.Constants"%>
<%@ include file="init.jsp"%>
<portlet:resourceURL var="getPlaces">
            <portlet:param name="<%=Constants.CMD%>" value="get_places" />
</portlet:resourceURL>
<aui:input id="myInputNode" name="myInputNode" label="Place"
            helpMessage="Type Some text in Input" />
<aui:script>
AUI().use('autocomplete-list','aui-base','aui-io-request','autocomplete-filters','autocomplete-highlighters',function (A) {
A.io.request('<%=getPlaces%>',{
dataType: 'json',
method: 'GET',
on: {
success: function() {
new A.AutoCompleteList(
{
allowBrowserAutocomplete: 'true',
activateFirstItem: 'true',
inputNode: '#<portlet:namespace />myInputNode',
resultTextLocator: 'name',
render: 'true',
resultHighlighter: 'phraseMatch',
resultFilters:['phraseMatch'],
source:this.get('responseData'),
})
}}
});
});
</aui:script>

Add following code in Portlet Action Class

@Override
             public void serveResource(ResourceRequest resourceRequest, ResourceResponse resourceResponse) throws IOException, PortletException {
               String cmd = ParamUtil.getString(resourceRequest, Constants.CMD);
             
              System.out.println("Constants.CMD: " + cmd);

              if (cmd.equals("get_places")) {
                getPlaceJson(resourceRequest, resourceResponse);
              }
             
            }

            private void getPlaceJson(ResourceRequest resourceRequest, ResourceResponse resourceResponse) throws IOException, PortletException {

              JSONArray jsonResults = JSONFactoryUtil.createJSONArray();
              try {
                String keyword = ParamUtil.getString(resourceRequest, "keywords");
                String searchPattern = keyword.replace("*", "%");

                System.out.println("Keywords: " + searchPattern);

                JSONObject jsonCells = JSONFactoryUtil.createJSONObject();
                jsonCells.put("key", "1");
                jsonCells.put("name", "New York, USA");
                jsonResults.put(jsonCells);
                jsonCells = JSONFactoryUtil.createJSONObject();
                jsonCells.put("key", "2");
                jsonCells.put("name", "Delhi, India");
                jsonResults.put(jsonCells);
                jsonCells = JSONFactoryUtil.createJSONObject();
                jsonCells.put("key", "3");
                jsonCells.put("name", "Hyderabad, India");
                jsonResults.put(jsonCells);
              } catch (Exception e) {
                         
              }
              PrintWriter out=resourceResponse.getWriter();
     out.println(jsonResults.toString());
            }

Populate Users Using AUI Auto Complete List

Add following code in JSP page

<%@page import="com.liferay.portal.kernel.util.Constants"%>
<%@ include file="init.jsp" %>
<portlet:resourceURL var="getUsers">
   <portlet:param name="<%=Constants.CMD%>" value="get_users" />
 </portlet:resourceURL>
 <aui:input id="myInputNode" name="myInputNode" label="User Email" helpMessage="Type User Email address in Input Box"/>
<aui:script>
AUI().use('autocomplete-list','aui-base','aui-io-request','autocomplete-filters','autocomplete-highlighters',function (A) {
A.io.request('<%=getUsers%>',{
dataType: 'json',
method: 'GET',
on: {
success: function() {
//continents=this.get('responseData');
//alert(continents[0].name);
new A.AutoCompleteList(
{
allowBrowserAutocomplete: 'true',
activateFirstItem: 'true',
inputNode: '#<portlet:namespace/>myInputNode',
resultTextLocator: 'email',
resultHighlighter:['phraseMatch'],
resultFilters:['phraseMatch'],
render: 'true',
source:this.get('responseData'),
});
}}
});                  
});
</aui:script>

Add following code in Portlet Action Class

@Override
             public void serveResource(ResourceRequest resourceRequest, ResourceResponse resourceResponse) throws IOException, PortletException {
               String cmd = ParamUtil.getString(resourceRequest, Constants.CMD);
if (cmd.equals("get_users")) {
 getUsers(resourceRequest, resourceResponse);
}
}
private void getUsers(ResourceRequest resourceRequest, ResourceResponse resourceResponse) throws IOException, PortletException {
JSONArray usersJSONArray = JSONFactoryUtil.createJSONArray();
ThemeDisplay themeDisplay = (ThemeDisplay)resourceRequest.getAttribute(WebKeys.THEME_DISPLAY);
JSONObject userJSON=null;
try {
List<User> userList=UserLocalServiceUtil.getUsers(0,
UserLocalServiceUtil.getCompanyUsersCount(themeDisplay.getCompanyId()));
                           for(User user:userList){
userJSON=JSONFactoryUtil.createJSONObject();
userJSON.put("userId",user.getUserId());
userJSON.put("email",user.getEmailAddress());
userJSON.put("firstName",user.getFirstName());
usersJSONArray.put(userJSON);
}
} catch (Exception e) {
}
PrintWriter out=resourceResponse.getWriter();
out.println(usersJSONArray.toString());
}

Populate Countries Using AUI Auto Complete List

Here we will call the portal Countries JSON web services URL and I hard coded the host name and port number. Please change host name and port number according to your environment, please login as admin and test this code because Portal web service call will be called only for authorized user.

Note:

We can also use JQuery Ajax to call web service with authorization header and the following is example for that


Add following code in JSP page

<%@page import="com.liferay.portal.kernel.util.Constants"%>
<%@ include file="init.jsp" %>
 <aui:input id="myInputNode" name="myInputNode" label="Country" helpMessage="Type Country Name in  Input Box"/>
<aui:script>
AUI().use('autocomplete-list','aui-base','aui-io-request','autocomplete-filters','autocomplete-highlighters',function (A) {
A.io.request('http://localhost:8080/api/jsonws/country/get-countries',{
dataType: 'json',
method: 'GET',
on: {
success: function() {
new A.AutoCompleteList(
{
allowBrowserAutocomplete: 'true',
activateFirstItem: 'true',
inputNode: '#<portlet:namespace/>myInputNode',
resultTextLocator: 'nameCurrentValue',
render: 'true',
resultHighlighter:['phraseMatch'],
resultFilters:['phraseMatch'],
source:this.get('responseData'),
})
}}
});
});
</aui:script>

Note:

For above code we need not write anything Portlet Action class because we are calling portal web service method.

Related Articles:



Reference Links:



Author

Popular Posts

Recent Posts

Recent Posts Widget