Friday, February 17, 2017

Pagination Problem in Liferay Search Container


We already see in detail how Search Container work in Liferay. But consider a scenario.

Let we have 9 records and we display 4 records on each page. So basically we have :-
a)2 pages with 4 records on each page
b)3rd page(last page) with only one record.

Now we delete record from 3rd page so ideally after deleting it will go to second page as now there are only 8 records . But in Liferay it will go to first page. So lets resolve this.Before reading this it is recommended to read search container in detail

Step 1:-Create Service Builder
My database table name is employee which contain only two fields eid and ename.

service.xml
<?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.service" auto-namespace-tables="false">
<author>aditya.bhardwaj</author>
<namespace>emplo</namespace>
<entity name="Employee" local-service="true" remote-service="false" table="employee">
<column name="eid" type="int" primary="true"></column>
<column name="ename" type="String"></column>
</entity>
</service-builder>
view raw service.xml hosted with ❤ by GitHub


Step 2:-Change your view
Inside your view paste this:-

view.jsp
<%@page import="javax.portlet.PortletURL"%>
<%@page import="com.liferay.portal.kernel.dao.search.SearchContainer"%>
<%@page import="com.liferay.portal.kernel.util.ListUtil"%>
<%@page import="com.service.model.Employee"%>
<%@page import="java.util.List"%>
<%@page import="com.liferay.portal.util.PortalUtil"%>
<%@page import="com.service.service.EmployeeLocalServiceUtil"%>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui"%>
<%@ taglib uri="http://liferay.com/tld/portlet" prefix="liferay-portlet" %>
<portlet:defineObjects />
<%
String currentURL = PortalUtil.getCurrentURL(request);
PortletURL portletURL = renderResponse.createRenderURL();
SearchContainer<Employee> employeeContainer= new SearchContainer<Employee>(renderRequest, null, null, SearchContainer.DEFAULT_CUR_PARAM, 4, portletURL, null, null);
List<Employee> employeeList = EmployeeLocalServiceUtil.getEmployees(employeeContainer.getStart(), employeeContainer.getEnd());
String cur = Integer.toString(employeeContainer.getCur());
String delta = Integer.toString(employeeContainer.getDelta());
int totalSize = EmployeeLocalServiceUtil.getEmployeesCount();
%>
<liferay-ui:search-container delta="4">
<liferay-ui:search-container-results results="<%= employeeList %>" total="<%= totalSize %>"/>
<liferay-ui:search-container-row className="com.service.model.Employee" modelVar="employeeObj">
<liferay-ui:search-container-column-text property="eid" />
<liferay-ui:search-container-column-text property="ename" />
<!-- For Delete URL -->
<portlet:actionURL var="deleteRecord" name="deleteRecord">
<portlet:param name="backURL" value="<%=currentURL %>" />
<portlet:param name="employeeId" value="${employeeObj.eid}" />
<portlet:param name="cur" value="<%=cur %>" />
<portlet:param name="delta" value="<%=delta %>" />
</portlet:actionURL>
<liferay-ui:search-container-column-text name="Delete Record" value="Delete" href="${deleteRecord}"/>
</liferay-ui:search-container-row>
<liferay-ui:search-iterator />
</liferay-ui:search-container>
view raw view.jsp hosted with ❤ by GitHub

Explanation:-
In the deleteRecord URL we send 4 parameters backURL, employeeId, cur and delta. Here :-
a)delta = number of records per page ie 4
b)cur = current page.
c)employeeId = id of employee which need to be deleted.
d)backURL = current URL





Step 3:-Change your Controller
Inside your java file paste this:-

Demo.java
package com.demo;
import java.io.IOException;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.util.bridges.mvc.MVCPortlet;
import com.service.service.EmployeeLocalServiceUtil;
public class Demo extends MVCPortlet {
public void deleteRecord(ActionRequest actionRequest,ActionResponse actionResponse) throws IOException, PortletException {
/*
* Get cur(current page) and delta(records per page) from URL
HttpServletRequest request = PortalUtil.getHttpServletRequest(actionRequest);
String cur = PortalUtil.getOriginalServletRequest(request).getParameter("_demo_WAR_searchcontainerportlet_cur");
String delta = PortalUtil.getOriginalServletRequest(request).getParameter("_demo_WAR_searchcontainerportlet_delta");
OR
*/
int cur = ParamUtil.getInteger(actionRequest, "cur");
int delta = ParamUtil.getInteger(actionRequest, "delta");
String backURL = ParamUtil.getString(actionRequest, "backURL");
int employeeId = ParamUtil.getInteger(actionRequest, "employeeId");
try {
EmployeeLocalServiceUtil.deleteEmployee(employeeId);
int totalRecord = EmployeeLocalServiceUtil.getEmployeesCount();
int maxPage ;// Maximum page after delete employee
if(totalRecord%delta != 0){
maxPage = totalRecord/delta +1;
}else{
maxPage = totalRecord/delta;
}
if(maxPage<cur){
String first = "_cur="+cur;
String second = "_cur="+maxPage;
backURL = backURL.replace(first, second);
}
actionResponse.sendRedirect(backURL);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
view raw Demo.java hosted with ❤ by GitHub

Explanation:-
We fetch all values and delete the record and after that i find the total number of pages by some calculation.Then If maximum page is less than current page than i simple change the _cur parameter from backURL  with maxpage and send the response to that page.


Step 4:-Check Output
Now when you delete record from last page it will redirect to second last page.

You can Download Source code from  Pagination Problem in Liferay Search Container. 



No comments:

Post a Comment

Total Pageviews

1042783

Number Of Unique Visitor

Free counters!