Monday, February 24, 2014

Liferay Auto Complete List with Ajax

Introduction:

Liferay Have given AUI Auto complete list from which we can populate matching values to user in input fields and data will be served from server with help of Ajax call.

AUI Auto Complete list need source property this specify the data which populated in input filtered.

This is very useful component in Liferay AUI so that we can populate exact matching result to end user instead of all available values.

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 AUI Auto Complete List with Ajax from following location

You can find source and war file


Portlet Screen-1:


Portlet Screen-2:


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 Liferay AUI Auto Complete List with Ajax.

Note:

Before use this portlet please Read entire Article and Use it
Go thorough following posts to get basic Understand about Liferay AUI Auto Complete List


Scenario: 1

Get all the data from server at one time and filter user desired values

In the last post I fetched the all values at one time to Input files and I am populating and when user type any string or letter It will display matching values.

Here only one time it requested to server through Ajax and gets all possible values to client side then AUI Auto Complete List will filter the values from all values at client side when user type something in input field.

Note:

Above scenario already covered in last post please has a look into following post.


Please read above article before start this article.

Scenario: 2

Get Matching Data from server for each user Input

In this scenario we will bring exact matching result from server for each time when use types something in input field.

Auto Complete List have capability to call back method for each user input so that we will use Ajax call to send request get the data from server.

I just took User table example so that when user type anything in input box I just search user based on email address that given by user.

Steps to implement
  1. Use AUI use function to load required AUI Java Script Modules.
  2. Create AUI Auto Complete List and pass required options
  3. Implement AUI IO Ajax in AUI Auto Complete List call back function
  4. Implement Server Resource Method in Portlet Action class to search data from user table.

Note:

We will use Server Resource method in portlet action class to server JSON Data and we will use Dynamic Query API to search user data from database.

The following is example 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>
<h2>Liferay Auto Complete List with Ajax</h2><br/>
<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) {
var testData;
new A.AutoCompleteList({
allowBrowserAutocomplete: 'true',
activateFirstItem: 'true',
inputNode: '#<portlet:namespace />myInputNode',
resultTextLocator:'email',
render: 'true',
resultHighlighter: 'phraseMatch',
resultFilters:['phraseMatch'],
source:function(){
var inputValue=A.one("#<portlet:namespace />myInputNode").get('value');
var myAjaxRequest=A.io.request('<%=getUsers.toString()%>',{
dataType: 'json',
method:'POST',
data:{
<portlet:namespace />userEmail:inputValue,
},
autoLoad:false,
sync:false,
on: {
success:function(){
var data=this.get('responseData');
testData=data;
}}
});
myAjaxRequest.start();
return testData;},
});
});
</aui:script>

Note:

When we use AUI IO Ajax call in Auto Complete List we need to first define AUI IO request and we need to start Ajax call with start method.

When we manually start Ajax call we need to make autoLoada false.

Go through following link more about AUI IO Request


The following sample code in Portlet Action Class

public class LiferayAUIAutoCompleteListWithAjaxAction extends MVCPortlet {
@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_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);
String userEmail = ParamUtil.getString(resourceRequest, "userEmail");
System.out.println("=====00000========" + userEmail);
DynamicQuery userQuery = DynamicQueryFactoryUtil.forClass(User.class,
PortalClassLoaderUtil.getClassLoader());
Criterion criterion = RestrictionsFactoryUtil.like("emailAddress",
StringPool.PERCENT + userEmail + StringPool.PERCENT);
userQuery.add(criterion);
JSONObject userJSON = null;
System.out.println("=====1111========" + userQuery.toString());
try {
List<User> userList = UserLocalServiceUtil.dynamicQuery(userQuery);
System.out.println("=====222========" + userList.size());
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());
}
}

Note:

In the above code we used Liferay Dynamic query to search user data from table, this pretty good mechanism and this is alternative to custom sql in liferay.

Related Articles:




Reference Links:





Author

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

Recent Posts

Recent Posts Widget

Popular Posts