7 Points for sortable column
1. What makes a Liferay Search Container Column sortable?
An attribute orderable=”true” to liferay-ui:search-container-column-text
2. How to define sorting order asc or desc?
An attribute orderByType=”asc” or orderByType=”desc” to liferay-ui:search-container tag.
3. What API should I use to sort columns?
org.apache.commons.beanutils.BeanComparator is the API that we can use to sort a specific column.
4. Do I need to download JAR for Apache Bean Comparator?
No. Liferay already has this JAR. Just need to use it.
5. What about custom comparator? Do I need it?
Yes and No. org.apache.commons.beanutils.BeanComparator can be used to sort any columns. However custom comparator can also be used. In this article custom comparator is not used.
6. Where should I write the sorting logic?
The sorting logic is too small. The sorting logic can be written both in JSP as well as in Portlet class. In this article the logic for sorting is explained in JSP.
7. What happens when a column header is sorted?
When a column header is clicked for sorting some parameters are passed in request scope. Two parameters orderByCol and orderByType are responsible sorting. orderByCol parameter says which column need to be sorted and orderByType parameter says in which order the column should be sorted. The value of orderByType should be either asc or desc.
JSP Code:
<%@page import="java.util.Collections"%> <%@page import="org.apache.commons.beanutils.BeanComparator"%> <%@page import="java.util.ArrayList"%> <%@page import="com.liferay.portal.kernel.util.ListUtil"%> <%@page import="com.liferay.portal.kernel.dao.orm.QueryUtil"%> <%@page import="com.liferay.portal.service.UserLocalServiceUtil"%> <%@page import="com.liferay.portal.model.User"%> <%@page import="com.liferay.portal.kernel.util.ParamUtil"%> <%@page import="com.liferay.portal.kernel.util.Validator"%> <%@page import="java.util.List"%> <%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%> <%@ taglib uri="http://liferay.com/tld/theme" prefix="theme"%> <%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %> <portlet:defineObjects /> <theme:defineObjects /> <% //orderByCol is the column name passed in the request while sorting String orderByCol = ParamUtil.getString(request, "orderByCol"); //orderByType is passed in the request while sorting. It can be either asc or desc String orderByType = ParamUtil.getString(request, "orderByType"); String sortingOrder = orderByType; //Logic for toggle asc and desc if(orderByType.equals("desc")){ orderByType = "asc"; }else{ orderByType = "desc"; } if(Validator.isNull(orderByType)){ orderByType = "desc"; } %> <liferay-ui:search-container orderByType="<%=orderByType %>" > <liferay-ui:search-container-results > <% //Get all the users from User_ table List<User> allUsers = UserLocalServiceUtil.getUsers(QueryUtil.ALL_POS,QueryUtil.ALL_POS); //usersPerPage is unmodifyable list. It can not be sorted. List<User> usersPerPage = ListUtil.subList(allUsers, searchContainer.getStart(),searchContainer.getEnd()); int totalUsers = UserLocalServiceUtil.getUsersCount() ; //From usersPerPage a new list sortableUsers is created. For sorting we will use this list List<User> sortableUsers = new ArrayList<User>(usersPerPage); if(Validator.isNotNull(orderByCol)){ //Pass the column name to BeanComparator to get comparator object BeanComparator comparator = new BeanComparator(orderByCol); if(sortingOrder.equalsIgnoreCase("asc")){ //It will sort in ascending order Collections.sort(sortableUsers, comparator); }else{ //It will sort in descending order Collections.reverse(sortableUsers); } } //sortableUsers list is sorted on the basis of condition. When page load it wont be sorted //It will be sorted only when a header of coulmn is clicked for sorting pageContext.setAttribute("results", sortableUsers); pageContext.setAttribute("total", totalUsers); %> </liferay-ui:search-container-results> <liferay-ui:search-container-row className="com.liferay.portal.model.User" modelVar="aUser" > <!-- orderableProperty="userId" this means that when this column is sorted orderByCol=userId is passed in the request--> <!-- if orderableProperty attribute is not mentioned then orderByCol=User Id is passed in request parameter at the time of sorting --> <!--orderable="true" means this column is sortable --> <!--Using name="User Id" we are saying that header should be User Id. If its not mentioned the header would be userId --> <liferay-ui:search-container-column-text property="userId" orderable="true" name="User Id" orderableProperty="userId" /> <liferay-ui:search-container-column-text property="status" orderable="true" /> <liferay-ui:search-container-column-text property="firstName" orderable="true" name="First Name" orderableProperty="firstName"/> <liferay-ui:search-container-column-text property="female" orderable="true" /> <liferay-ui:search-container-column-text property="emailAddress" orderable="true" name="Email Address" orderableProperty="emailAddress"/> <liferay-ui:search-container-column-text property="lastName" orderable="true" name="Last Name" orderableProperty="lastName"/> </liferay-ui:search-container-row> <liferay-ui:search-iterator /> </liferay-ui:search-container>
Note 1: Please read the code comments for clear understanding of the code.
Note 2: The default functionality of search container should pass toggle asc or desc order type at the of sorting. But it is not happening.May be it is a bug. So custom toggle code is written.
Note 3:
List<User> usersPerPage = ListUtil.subList(allUsers, searchContainer.getStart(),searchContainer.getEnd());
is unmodifiable list. You can not sort it. Just create another list from it to make it modifiable.
Note 4: By default org.apache.commons.beanutils.BeanComparator is not available in plugin portlet. However you can make it available by including portal dependency in liferay-plugin-package.properties.
Sample Screen Shot: