Liferay’s Search container provides developers a easy way of implementing tabular representation of data along with pagination, ordering and other capabilities. This is a liferay-ui tag library component.

Let’s create a simple search container to iterate and display Employee details from database and also add sorting capabilities to different columns.

searchContainer1

  • Create a service.xml file, and add the following content to create an entity called “EmployeeDetails” as shown below and build service. To know more about service builder, click here.
<?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.sc"> 
  <author>ASB</author> 
  <namespace>Arun</namespace> 
  <entity name="EmployeeDetails" local-service="true" remote-service="false"> 
    <column name="empId" type="long" primary="true" /> 
    <column name="empName" type="String" /> 
    <column name="Dept" type="String" /> 
  </entity>
</service-builder>
  • To use the search container, we have to import liferay UI tag library into our jsp page.
<%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>
  • Add the following code inside view.jsp. Here, we are orderByType and orderByCol variables to, which are passed from search container to render phase, every time any column header is clicked. These parameters are available on every render request.
  • Initially, if request parameter “orderByType ” and “orderByCol ” are empty, we are setting order to ascand “empName” respectively.  
  • The “orderByType ” parameter is used to inform the search container, on the column, which order(asc/desc) to be applied.

View.jsp:

<%@page import="com.liferay.portal.kernel.util.ParamUtil"%>
<%@page import="com.liferay.portal.kernel.util.ParamUtil"%>
<%@page import="com.asb.sc.service.EmployeeDetailsLocalServiceUtil"%>
<%@page import="com.asb.sc.model.EmployeeDetails" %>
<%@page import="java.util.List" %>
<%@page import="java.util.ArrayList" %>
<%@page import="com.asb.sc.util.EmployeeDtlsComparatorUtil" %>
<%@page import="com.liferay.portal.kernel.util.ListUtil"%>
<%@page import="javax.portlet.PortletURL"%>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>
<portlet:defineObjects />

<h3>Orderable Search Container Example</h3>

<% PortletURL portletURL = renderResponse.createRenderURL(); 
portletURL.setParameter("jspPage", "/view.jsp"); 
String orderByCol = ParamUtil.getString(request, "orderByCol"); 
String orderByType = ParamUtil.getString(request, "orderByType"); 
if(orderByCol==null || orderByCol.equals("")) { 
   orderByCol="empName"; request.setAttribute("orderByCol",orderByCol); 
} if(orderByType==null || orderByType.equals("")) { 
   orderByType="asc";         
   request.setAttribute("orderByType",orderByType); 
} 
//Logic for toggle asc and desc on rendering the page 
if(orderByType.equals("desc")){     
   orderByType = "asc"; 
}else{     
   orderByType = "desc"; 
}%>
<liferay-ui:search-container orderByType="<%=orderByType%>" delta="3" 
   iteratorURL="<%=portletURL%>"> 
   <liferay-ui:search-container-results> 
    <% 
      List<EmployeeDetails> empList = EmployeeDetailsLocalServiceUtil.getEmployeeDetailses(-1, -1); 
      //Get a local copy so that it can be sorted based on our needs.
      List<EmployeeDetails> sortableUsers = new ArrayList<EmployeeDetails>
      (ListUtil.subList(empList, searchContainer.getStart(), searchContainer.getEnd())); 
      
      //Sort the list based on order and column:
      sortableUsers = EmployeeDtlsComparatorUtil.sortEmployeeDtls(sortableUsers, 
                       orderByCol, orderByType);     
      pageContext.setAttribute("results", sortableUsers);     
      pageContext.setAttribute("total", empList.size()); 
   %> 
  </liferay-ui:search-container-results> 
<liferay-ui:search-container-row className="com.asb.sc.model.EmployeeDetails" modelVar="empDtls" > 
   <liferay-ui:search-container-column-text property="empId" name="Employee Id" orderable="true" orderableProperty="empId"/> 
   <liferay-ui:search-container-column-text property="dept" orderable="true" orderableProperty="dept"/> 
   <liferay-ui:search-container-column-text property="empName" orderable="true" orderableProperty="empName"/> 
   </liferay-ui:search-container-row> <liferay-ui:search-iterator />
</liferay-ui:search-container>
  • We are using a custom class, EmployeeDtlsComparatorUtil to sort the list which is passed to the method sortEmployeeDtls along with column and order.
  • We are setting the results  and total attributes to pageContext, so that it will always be available for search container.
  • For <liferay-ui:search-container-row> component, we pass Entity class as className attribute. we also set a modelVar, which can be used for referring entity value on each column item.
  • <liferay-ui:search-container-column-text> tag is used to print the values of each column. fallowing are few properties used and it’s meaning:

property : Property name of the entity column.
orderable: true will enable the orderable property for that column.
orderableProperty : Property value, for which order is applied.
name : Name for the column.

  • Create a Util class called “EmployeeDtlsComparatorUtil ” and add the following code. Here we have different comparator implementation for each column with both ascending and descending order. These are invoked from view.jsp based on column and order type.
package com.asb.sc.util;
package com.asb.sc.util;
import com.asb.sc.model.EmployeeDetails;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class EmployeeDtlsComparatorUtil {
 public static List<EmployeeDetails> sortEmployeeDtls(List<EmployeeDetails> empList, String orderByCol, String orderByType){ 
  if(orderByCol.equals("empName")) {     
   if(orderByType.equals("asc")) { 
    Collections.sort(empList, EmployeeDtlsComparatorUtil.empNameAsc);     
   }
   else {     
     Collections.sort(empList, EmployeeDtlsComparatorUtil.empNameDesc);     
    }     
  } 
  else if(orderByCol.equals("dept")) {     
   if(orderByType.equals("asc")) { 
    Collections.sort(empList, EmployeeDtlsComparatorUtil.empDeptAsc);     
   }else {     
    Collections.sort(empList, EmployeeDtlsComparatorUtil.empDeptDesc);     
   }
  }     
  else if(orderByCol.equals("empId")) {     
   if(orderByType.equals("asc")) { 
    Collections.sort(empList, EmployeeDtlsComparatorUtil.empIdAsc);     
   }else {     
    Collections.sort(empList, EmployeeDtlsComparatorUtil.empIdDesc);     
   }    
   } 
  return empList; 
} 

public static Comparator<EmployeeDetails> empNameAsc = new Comparator<EmployeeDetails>() { 
  @Override public int compare(EmployeeDetails o1, EmployeeDetails o2) { 
    EmployeeDetails empDtls1 = (EmployeeDetails) o1; 
    EmployeeDetails empDtls2 = (EmployeeDetails) o2; 
    int value = empDtls1.getEmpName().toLowerCase().compareTo(empDtls2.getEmpName().toLowerCase()); 
    return value; 
  }            
  // compare using attribute 1        
};         

public static Comparator<EmployeeDetails> empNameDesc = new Comparator<EmployeeDetails>() { 
  @Override public int compare(EmployeeDetails o1, EmployeeDetails o2) { 
   EmployeeDetails empDtls1 = (EmployeeDetails) o1; 
   EmployeeDetails empDtls2 = (EmployeeDetails) o2; 
   int value = empDtls2.getEmpName().toLowerCase().compareTo(empDtls1.getEmpName().toLowerCase()); 
   return value; 
  }        
};         

public static Comparator<EmployeeDetails> empDeptAsc = new Comparator<EmployeeDetails>() { @Override public int compare(EmployeeDetails o1, EmployeeDetails o2) { 
   EmployeeDetails empDtls1 = (EmployeeDetails) o1; 
   EmployeeDetails empDtls2 = (EmployeeDetails) o2; 
   int value = empDtls1.getDept().toLowerCase().compareTo(empDtls2.getDept().toLowerCase()); 
   return value; 
  }        
};         

public static Comparator<EmployeeDetails> empDeptDesc = new Comparator<EmployeeDetails>() { 
  @Override public int compare(EmployeeDetails o1, EmployeeDetails o2) { 
   EmployeeDetails empDtls1 = (EmployeeDetails) o1; 
   EmployeeDetails empDtls2 = (EmployeeDetails) o2; 
   int value = empDtls2.getDept().toLowerCase().compareTo(empDtls1.getDept().toLowerCase()); 
   return value; 
  }        
};                

public static Comparator<EmployeeDetails> empIdAsc = new Comparator<EmployeeDetails>() { 
 @Override public int compare(EmployeeDetails o1, EmployeeDetails o2) { 
   EmployeeDetails empDtls1 = (EmployeeDetails) o1; 
   EmployeeDetails empDtls2 = (EmployeeDetails) o2; 
   boolean value = empDtls1.getEmpId() > empDtls2.getEmpId(); 
   if(value){ 
      return 1; 
   } else { 
      return -1; 
   } 
  }        
};                
public static Comparator<EmployeeDetails> empIdDesc = new Comparator<EmployeeDetails>() { 
 @Override public int compare(EmployeeDetails o1, EmployeeDetails o2) { 
  EmployeeDetails empDtls1 = (EmployeeDetails) o1; 
  EmployeeDetails empDtls2 = (EmployeeDetails) o2; 
  boolean value = empDtls2.getEmpId() > empDtls1.getEmpId(); 
   if(value){ 
     return 1;
   } else { 
    return -1; 
   }
  }        
};
}
  • Finally, output looks as shown below:

Sc2

For all Liferay related posts, click here.

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