Thursday, November 30, 2006

Struts: Paging and Sorting with Displaytag

In the previous post, I described the use of Displaytag to implement paging in a simple JSP. In this example, I describe the use of Displaytag to implement sorting along with paging in Struts.
Skip to Sample Code
In this example, we take a single input field, which is used to filter the employee list based on the minimum salary. Follow these steps to implement the solution.
  1. Start by importing struts-blank.war file into Eclipse.
  2. Follow the configuration steps 1, 2, 4, 5, and 6 in from the "Pagination with Displaytag" post.
  3. Create the search page as shown below
    <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
    <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean"%>
    <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
    <%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic"%>
    <%@ taglib uri="http://displaytag.sf.net" prefix="display"%>
    <%@ page import="beans.Employee,data.DAO,java.util.List,org.displaytag.tags.TableTagParameters,org.displaytag.util.ParamEncoder"%>
    <html:html>
    <head>
    <title>Search page</title>
    <link rel="stylesheet" type="text/css"
    href="/StrutsPaging/css/screen.css" />
    </head>
    <body bgcolor="white">
    <html:form action="/search.do">
    <table>
    <tr>
    <td>Minimum Salary:</td>
    <td><html:text property="minSalary"></html:text></td>
    </tr>
    <tr>
    <td colspan="2"><html:submit property="submit" /></td>
    </tr>
    </table>
    </html:form>
    <logic:notEqual name="empList" value="null">
    <jsp:scriptlet>
    if (session.getAttribute("empList") != null) {
    String sortBy = request.getParameter((new ParamEncoder("empTable")).encodeParameterName(TableTagParameters.PARAMETER_SORT));
    DAO.sort((List) session.getAttribute("empList"), sortBy);
    }
    </jsp:scriptlet>

    <display:table name="sessionScope.empList" pagesize="4" id="empTable" sort="external" defaultsort="1" defaultorder="ascending">
    <display:column property="empId" title="ID" sortable="true" sortName="empId" headerClass="sortable" />
    <display:column property="empName" title="Name" sortName="empName" sortable="true" headerClass="sortable" />
    <display:column property="empJob" title="Job" sortable="true" sortName="empJob" headerClass="sortable" />
    <display:column property="empSal" title="Salary" sortable="true" headerClass="sortable" sortName="empSal" />
    </display:table>
    </logic:notEqual>
    </body>
    </html:html>
    pages/search.jsp
    Note that
    1. The display:table tag has the sort attribute defined as "external".
    2. Since the sort type is external, we have to provide for the actual sorting, which I implemented in the DAO class itself (see below).
    3. The column to sort by is obtained by the following peice of code
      request.getParameter((new ParamEncoder("empTable")).encodeParameterName(TableTagParameters.PARAMETER_SORT))
  4. Create the Action class and Form bean as shown below.
    public class SearchAction extends Action {
    public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse httpservletresponse) throws Exception {
    if (form == null) {
    return mapping.findForward("success");
    }
    try {
    SearchForm searchForm = (SearchForm) form;
    if (searchForm.getMinSalary().equals("")) {
    return mapping.findForward("success");
    }
    long minSal = Long.parseLong(searchForm.getMinSalary());
    List data = DAO.getData(minSal);

    request.getSession().setAttribute("empList", data);

    } catch (Exception e) {
    e.printStackTrace();
    }
    return mapping.findForward("success");
    }
    }
    actions.SearchAction
    public class SearchForm extends ActionForm {
    private String minSalary;
    public String getMinSalary() {
    return minSalary;
    }
    public void setMinSalary(String minSalary) {
    this.minSalary = minSalary;
    }
    }
    forms.SearchForm.java
  5. Modify the struts-config.xml to include the action and actionform as shown below
    <form-beans>
    <form-bean name="searchForm" type="forms.SearchForm" />
    </form-beans>
    <action-mappings>
    <action path="/Welcome" forward="/pages/Welcome.jsp" />
    <action name="searchForm" path="/search"
    type="actions.SearchAction" scope="session">
    <forward name="success" path="/pages/search.jsp"></forward>
    </action>
    </action-mappings>
  6. Create the DAO class as shown below
    public class DAO {
    public static List getData(long minSal) {
    SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
    Session session = sessionFactory.getCurrentSession();
    List result = null;
    try {
    session.beginTransaction();
    result = session.createQuery("from Employee as emp where emp.empSal >=?").setLong(0, minSal).list();
    System.out.println("Result size : " + result.size());
    session.getTransaction().commit();
    } catch (Exception e) {
    e.printStackTrace();
    }
    return result;
    }

    public static List sort(List<Employee> list, String sortBy) {
    Comparator comp = getComparator(sortBy);
    Collections.sort(list, comp);
    return list;
    }

    private static Comparator getComparator(String sortBy) {
    System.out.println("Sort by : " + sortBy);
    if (sortBy ==null) {
    return new NameComparator();
    }
    if (sortBy.equals("empName"))
    return new NameComparator();
    if (sortBy.equals("empId"))
    return new IdComparator();
    if (sortBy.equals("empSal"))
    return new SalComparator();
    if (sortBy.equals("empJob"))
    return new JobComparator();

    return null;

    }

    private static class NameComparator implements Comparator {
    public int compare(Object emp1, Object emp2) {
    Employee employee1 = (Employee) emp1;
    Employee employee2 = (Employee) emp2;
    return employee1.getEmpName().compareTo(employee2.getEmpName());
    }
    }

    private static class IdComparator implements Comparator {
    public int compare(Object emp1, Object emp2) {
    Employee employee1 = (Employee) emp1;
    Employee employee2 = (Employee) emp2;
    return new Long(employee1.getEmpId()).compareTo(new Long(employee2.getEmpId()));
    }
    }

    private static class SalComparator implements Comparator {
    public int compare(Object emp1, Object emp2) {
    Employee employee1 = (Employee) emp1;
    Employee employee2 = (Employee) emp2;
    return new Long(employee1.getEmpSal()).compareTo(new Long(employee2.getEmpSal()));
    }
    }

    private static class JobComparator implements Comparator {
    public int compare(Object emp1, Object emp2) {
    Employee employee1 = (Employee) emp1;
    Employee employee2 = (Employee) emp2;
    return employee1.getEmpJob().compareTo(employee2.getEmpJob());
    }
    }

    }
    DAO.java
    Note here that
    1. The list sorting is done in this class itself.
    2. The Comparators are used to compare order the list based on each individual field (there may be scope for improvement here).

40 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. Anand, I'm not quite sure, you have to be more explicit.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. I meant, the jsp is already in the post. Did you want to know any specific details of the jsp I am using?

    ReplyDelete
  5. K sir. I got it. I ll make use of it. can i ask any further queries to you

    ReplyDelete
  6. sure, no problem. I can't promise I'll have all the answers though :).

    ReplyDelete
  7. Abhi, sorry for disturbing you often. Can you help me once again.

    I have hundreds of datas in my database, how can i show those details in a webpage in jsp using paging logic. You have any sample codes for that.


    Thanx in advance...........

    ReplyDelete
  8. Please refer to the previous post
    http://java-x.blogspot.com/2006/11/pagination-with-displaytag.html
    this handles simple pagination without struts. I wouldn't advise you to put a lot of logic in you JSP. However if you don't want to use displaytag (like when the dataset is too large), then you have to consider using hibernate's setMaxResults(int maxResults) and setFirstResult(int firstResult) methods of the Query interface. The example in this post and the previous one use hibernate to fetch data. I will see if I can post an example of this as soon as I get some free time.

    Implementing the whole thing yourself (without hibernate) will take too much time and might not be bug free.

    ReplyDelete
  9. I was just wondering if you'd had any odd problems. In particular, I've got most everything working, except that, at the top and bottom of the table, it says "x items found, displaying y to z". The problem I keep having is that y and z are always 1 and 25 (unless the page shows only fewer records, in which case the second number changes to something which is still wrong. I thought maybe it was a matter of setting "offset", but that results in even weirder behavior.

    Does any of that ring any bells?

    Thanks,

    -D

    ReplyDelete
  10. I haven't seen such behavior. Did you are you getting this behavior with the example shown here. Is there anything different that you are trying?

    ReplyDelete
  11. I forgot to mention that I'm using the partialList option, which is likely part of the problem.

    -D

    ReplyDelete
  12. I am not sure how you are using the tag, but the problem could be with the size attribute, is it available in a scope visible to displaytag?

    ReplyDelete
  13. Hey Abhi,

    Is there a way that we can implement multilevel sorting here.
    sort by column and then by column b..

    ReplyDelete
  14. Hi,

    Using DisplayTag pagination feature, do I have to always store the list in the session? My list can be womewhat large and I would like to get a page of data everytime they click on Next, Previous, First and Last links. Is this possible?

    Thanks,

    Kaveh

    ReplyDelete
  15. i have a nested list containing 5 lists ,can i use dispaly tag to display the data.i also have to implement paging for that paging

    ReplyDelete
  16. This comment has been removed by the author.

    ReplyDelete
  17. Hi Abhi,
    I am Srikanth, I am doing now pagenavigaton in jsp.I am not using Hibernet and struts. i am using netonomy framework.i had my total data as a array of objects in jsp.Now i want to display it by using paging.in my jsp.How can i use this displaytag for my applicaiton.my email id srikanth.scjp@gmail.com. Please help me for this

    ReplyDelete
  18. This comment has been removed by the author.

    ReplyDelete
  19. This comment has been removed by the author.

    ReplyDelete
  20. Hi,
    I am using a display tag for pagination in my JSP page. I have a checkbox field as one of the columns. I am using displayTagWrapper class to display my checkboxes. I also have pagination and sorting in the page.

    The problem i have is, i will loose the status of the checkbox when i go to second page. If i select some of the checkboxes in page 1 and go to page 2 to select some more and if i come back, i loose all the selected checkboxes in page 1.

    Is there a way where i could save my check boxes in session and its checked while i browse across pages and gets submitted all at once.

    Thanks in advance

    ReplyDelete
  21. Hi Abhi,

    Can you pls tell me using your same example, I like to ask that if i have records more 10000 than it will be like load on session variable. Can you suggest me any caching method for same using same example. I will helpful for me..

    Saurabh,
    saurabh.more@gmail.com

    ReplyDelete
  22. Hi

    Im able to display te data page wise using the display tag.

    display:table pagesize="6" name="empList" id="empList" requestURI="/edit/systemPhoto.do"

    display:column property="empNo" title="Employee No" /
    display:column property="empName" title="Name" /

    /display:table

    I want to to assign the value of the empNo displayed using display column to a variable. Is that possible?

    ReplyDelete
  23. Hi,

    I am using displaytag for pagination in pure struts based web application.

    I am facing a problem.

    When i am on second page and i click a column for sorting, it doesnt sort for the current page, but it sorts for 1st page.

    I am not seeing d-tableid-p attribute in the querystring while sorting. Can you please tell me how do i get page number in my action class while sorting the data?

    its urgent...
    Thanks in advance for ur help...

    Rashmi

    ReplyDelete
  24. Hi Abhi,'

    I am using displaytag for pagination. Along with sorting problem, i have one more problem.
    I want to show checkboxes for a column. also i want to set then checked or unchecked on the basis of column value.

    Can you give me a sample code for showing checkboxes using displaytag?

    ur help would be appreciated.

    thanks
    Rashmi

    ReplyDelete
  25. hi abhi,

    i am having problem with nested table
    in display tag.can you show me a example of how it works.

    i used two lists for nested table..
    the child table displays nothing found to display...

    But parent shows the list..

    ReplyDelete
  26. hi... i hv some problem .. my display tag have one column that have more than one field to be key-n such as textarea, text area, input value from calendar and radio button.. i wanna ask u, if i key-in in first page, how i carry that value to the next page.. there is Save function - allow user to save all record, in whatever page he edit...

    ReplyDelete
  27. HI,

    Considering there are 2 users. they view thesame url with list of data (Using Displaytag pagination) that has 3 pages. when user1 is still at the 1st page and user2 added 5 records at thesame time. How can i update the data of user1 added by user2 when nextpage is clicked.

    ReplyDelete
  28. Hi abhi,

    Do u have a sample codes of displaytag using struts portlet(JSR 168)? If u know how to implement this can u please email it to me in jhay_are1984@yahoo.com
    Thanks

    ReplyDelete
  29. Hi,
    I am using a display tag for pagination in my JSP page. I have a checkbox field as one of the columns. I am using displayTagWrapper class to display my checkboxes. I also have pagination and sorting in the page.

    The problem i have is, i will loose the status of the checkbox when i go to second page. If i select some of the checkboxes in page 1 and go to page 2 to select some more and if i come back, i loose all the selected checkboxes in page 1.

    Is there a way where i could save my check boxes in session and its checked while i browse across pages and gets submitted all at once.

    Thanks in advance

    ReplyDelete
  30. Hi
    I have one problem.
    I am able to sort data but what happens suppose i m on 4th page and i click on column to sort it then after sorting it goes back to first page.how can i maintain the current page

    ReplyDelete
  31. Hi I'm working with Struts using My Eclipse and MySQL.. Can u tell me the code for displaying a particular column from the database in combobox through jsp . I want both the java action coding and the jsp coding. can u help me with this..

    ReplyDelete
  32. ,rashmi said...

    Hi,

    I am using displaytag for pagination in pure struts based web application.

    I am facing a problem.

    When i am on second page and i click a column for sorting, it doesnt sort for the current page, but it sorts for 1st page.

    I am not seeing d-tableid-p attribute in the querystring while sorting. Can you please tell me how do i get page number in my action class while sorting the data?

    its urgent...
    Thanks in advance for ur help...

    Rashmi




    i have the same problem

    ReplyDelete
  33. i think i have solved looking here
    http://www.tutorialized.com/view/tutorial/Struts-Pagination-and-Sorting-using-Display-tag-Tutorial/41740

    ReplyDelete
  34. http://www.tutorialized.com/view/tutorial/Struts-Pagination-and-Sorting-using-Display-tag-Tutorial/41740

    The above link is good example for sorting and paging for a struts based web application but it is working only for independent page not in tiles. Any idea? please let me know at bhagat.rawat@gmail.com

    ReplyDelete
  35. hello abhi,
    i wants to use the paginatedList class , i am using the struts, Hibernate, can u guid me about how to implement PaginatedList to display the only 10 rows amoung 10000 row at a time

    ReplyDelete
  36. Hi Abhi
    I am using displaytag in my application with struts-2 and it is working fine.
    Do you know how to display the pagination list in the bottom of the table?

    ReplyDelete
  37. Hi Abhi
    I am using displaytag in my application with struts-2 and it is working fine.But there are too many records in the DB so everytime it is fetching all records when the page links.could you please help me to do the external paging and sorting using displaytag in struts2.I searched in internet but i didnt get clear idea of how to implement it. Please help me to solve the issue.

    ReplyDelete
  38. Hi, Abhi! Very good!

    Could you help me?

    I have a problem: when I change the page, the sorting by column is lost.

    Example: I have two columns in my app (id, name), and originally, the query executed in the database is sorted by the column 'name' in ascending order. If I click on the column 'name' again, the sort will be done in descending order. The problem happens when I click to go to another page ... sort of reference is lost. How can I preserve it?

    Thank you for your attention.

    ReplyDelete
  39. Hi Abhi,

    Need some help.
    I am actually using the displaytag export to excel option. I have numbers leading with zero's, while exporting to excel, it is formatted and leading zero's are removed. Is there any way I to prevent that?

    Thank you,
    Abhishek

    ReplyDelete

Popular Posts