Site icon Pro Liferay

Liferay Search Container Sorting

Search Container Sorting

Liferay Search Container is the great way to display your data in a grid format with nice pagination. One beauty of search container is that it’s very flexible and configurable. Do you want to sort one or more header columns? Then this is the article for you. It explains the nut and bolts to sort liferay search container headers.

 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 sortedThe 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:

Exit mobile version