[ http://jira.codehaus.org/browse/DISPL-263?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_88778 ]
Jose Lima commented on DISPL-263: --------------------------------- I have an application running in Spring and using displaytag. In some screens there are lists of elements with pagination and options to edit an entry. After editing an entry in any page it is desired to be placed back on the same page, instead of always the first - which occurs now. I though about using this patch to solve the problem, but I wonder if there is something in the actual code (version 1.1) that would be more advisable to use? Many thanks in advance for any help, > Session-enabled display tag library > ----------------------------------- > > Key: DISPL-263 > URL: http://jira.codehaus.org/browse/DISPL-263 > Project: DisplayTag > Issue Type: New Feature > Components: Paging/Sorting > Affects Versions: 1.1 > Priority: Minor > Fix For: TBD > > Attachments: DisplaytagColumnSortFilter.java, ParamEncoder.java, > TableTag.java > > Original Estimate: 5 days > Remaining Estimate: 5 days > > > Session-enabled display tag library > ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- > The display tag library is not session-enabled i.e., the sorting and > paginnation is not preserved across the session. Sometimes its desirable that > the previously selected sorting or page is shown again to the user when the > user revists a page. To make display tag library session-aware we did the > following changes: > org.displaytag.tags.TableTag class > --------------------------------------------- > The initParameters( ) method of TableTag class encodes the current page > number, sort column index and sort order and stores it in instance variables. > These instance variables form part of the request URL to ensure that the > sorting ( ascending / descending ) is preserved across multiple interaction > with the table shown on the web page. To encode current page number, sort > column index and sort order, the TableTag class makes use of the > encodeParameter ( .. ) method, which accepts a prefix to be used when > encoding a parameter. The following code from > org.displaytag.tags.TagTagParameters class shows the values that are passed > to the encodeParameter ( ... )method: > /** > * name of the parameter specifying the current sorted column index. > */ > public static final String PARAMETER_SORT = "s"; //$NON-NLS-1$ > /** > * name of the parameter specifying the current page number. > */ > public static final String PARAMETER_PAGE = "p"; //$NON-NLS-1$ > /** > * name of the parameter specifying the current sorting order. > */ > public static final String PARAMETER_ORDER = "o"; //$NON-NLS-1$ > The encodeParameter (...s) method makes use of > org.displaytag.util.ParamEncoder class to generate unique parameter names. > The contructor of ParamEncoder class accepts a unique id. This unique id is > nothing but the uid attribute of <display:table> tag. The display tag > documentation mentions that two tables on the same page MUST NOT have same > uid, because if you keep them same then it won't be possible for the display > tag library to distinguish between the two tables. > If two tables on the same web page have same uid then the actions taken on > one table will apply on the other table also because display tag won't be > able to distinguish between the two tables. If the uid for two tables ( on > the same web page ) are different then the encodeParameter method will create > different unique parameter names because it makes use of uid attribute when > generating parameter names. > Note: We earlier modified the display tag library to fix problem related to > pagination because of which our first page is designated as 1. If you are > using the fixes provided by display tag team then instead of 1, use 0 before > using the code below. > When using display tag you may have seen something like the following in the > URL: > d-49653-p=1&d-49653-o=2&d-49653-s=2 > d-49653-p - encoded parameter corresponding to the current page number > d-49653-o - encoded parameter corresponding to the sort order > d-49653-s - encoded parameter corresponding to the sort column > The p, o and s in the encoded parameter comes from the constants defined in > TableTagParameters ( see above ). > Problems involved in making display tag library session-aware > Adding the encoded parameter name and value into the session > Lets say a user moves from web page A ( which contains table T1 ) to a > web page B ( which contains table T2 ). If T1 and T2 tables have the same uid > attribute then the resulting encoded parameter names will have the same name > i.e., if on web page B we add encoded parameter name and value corresponding > to table T2 in the session then it will overwrite the encoded parameter > corresponding to the table T1. > If it is required to remove the encoded parameters from the session > then how a developer can generate the encoded parameter names > programmatically. > Adding the encoded parameter name and value into the session > The initParameter( ) method of TableTag was modified to add the encoded > parameter name and value into the session: > > Adding encoded page parameter to the session > Integer pageNumberParameter = > requestHelper.getIntParameter(encodeParameter(TableTagParameters.PARAMETER_PAGE)); > if(pageNumberParameter == null) { > // If the encoded page parameter exists in the session then obtain its value. > // Else add the encoded page parameter to the session and sets its value to 1. > Object objPageParameter = > this.pageContext.getSession().getAttribute(encodeParameter(TableTagParameters.PARAMETER_PAGE)); > if(objPageParameter != null) { > pageNumberParameter = (Integer)objPageParameter; > } else { > pageNumberParameter = new Integer(1); > > this.pageContext.getSession().setAttribute(encodeParameter(TableTagParameters.PARAMETER_PAGE), > pageNumberParameter); > } > } > this.pageContext.getSession().setAttribute(encodeParameter(TableTagParameters.PARAMETER_PAGE), > pageNumberParameter); > this.pageNumber = pageNumberParameter.intValue(); > Integer sortColumnParameter = > requestHelper.getIntParameter(encodeParameter(TableTagParameters.PARAMETER_SORT)); > if( sortColumnParameter == null ) { > Object objSortParameter = > this.pageContext.getSession().getAttribute(encodeParameter(TableTagParameters.PARAMETER_SORT)); > if( objSortParameter != null ) { > sortColumnParameter = (Integer)objSortParameter; > } else { > sortColumnParameter = new Integer(this.defaultSortedColumn); > > this.pageContext.getSession().setAttribute(encodeParameter(TableTagParameters.PARAMETER_SORT), > sortColumnParameter); > } > } > this.pageContext.getSession().setAttribute(encodeParameter(TableTagParameters.PARAMETER_SORT), > sortColumnParameter); > int sortColumn = sortColumnParameter.intValue(); > Integer sortColumnParameter = > requestHelper.getIntParameter(encodeParameter(TableTagParameters.PARAMETER_SORT)); > if( sortColumnParameter == null ) { > Object objSortParameter = > this.pageContext.getSession().getAttribute(encodeParameter(TableTagParameters.PARAMETER_SORT)); > if( objSortParameter != null ) { > sortColumnParameter = (Integer)objSortParameter; > } else { > sortColumnParameter = new Integer(this.defaultSortedColumn); > > this.pageContext.getSession().setAttribute(encodeParameter(TableTagParameters.PARAMETER_SORT), > sortColumnParameter); > } > } > this.pageContext.getSession().setAttribute(encodeParameter(TableTagParameters.PARAMETER_SORT),sortColumnParameter); > int sortColumn = sortColumnParameter.intValue(); > Integer sortCode = > requestHelper.getIntParameter(encodeParameter(TableTagParameters.PARAMETER_ORDER)); > SortOrderEnum paramOrder = SortOrderEnum.fromCode(sortCode); > if(paramOrder == null) { > Object objSortParameter = > > this.pageContext.getSession().getAttribute(encodeParameter(TableTagParameters.PARAMETER_ORDER)); > if(objSortParameter != null) { > paramOrder = (SortOrderEnum)objSortParameter; > } else { > paramOrder = this.defaultSortOrder; > } > } > this.pageContext.getSession().setAttribute(encodeParameter(TableTagParameters.PARAMETER_ORDER), > paramOrder); > Differentiating two tables on different web pages with same uid > To take care of this situation we modified the ParamEncoder class constructor > to accept 'requestURI' ( you can use 'uid' attribute instead ) attribute > value also. > private String encodeParameter(String parameterName) { > // paramEncoder has been already instantiated? > if (this.paramEncoder == null) > { > // use the id attribute to get the unique identifier > // If the <display:table> tag encloses another <display:table> > then pass this information to ParamEncoder to ensure > // different encoded parameter is generated. > TableTag tableTag = (TableTag)findAncestorWithClass(this, > TableTag.class); > HttpServletRequest request = > (HttpServletRequest)this.pageContext.getRequest(); > if(tableTag != null) { > this.paramEncoder = new ParamEncoder(getUid(), true, requestUri); > } else { > this.paramEncoder = new ParamEncoder(getUid(), false, > requestUri); > } > } > return this.paramEncoder.encodeParameterName(parameterName); > } > public ParamEncoder(String idAttribute, boolean parentFound, String uri) > { > // use name and id to get the unique identifier > String stringIdentifier = "x-" + idAttribute; //$NON-NLS-1$ > if(uri != null) { > stringIdentifier = stringIdentifier + uri; > } > .... > .... > if( parentFound ) { > this.parameterIdentifier = "z-" + checkSum + "-"; //$NON-NLS-1$ > //$NON-NLS-2$ > } else { > this.parameterIdentifier = "d-" + checkSum + "-"; //$NON-NLS-1$ > //$NON-NLS-2$ > } > } > Removing encoded parameters from the session > Lets say that you use display tag to show 10 records per page. If there are > 15 records then two page will be shown to the user. The problem occurs when > the user has the option to delete records from the table shown. If the user > deletes the last 5 records from the last page then the session is corrupted > because encoded parameter for the page number will refer to the last page > i.e, 2nd page, which no longer exists. Its been observed that this results in > distorted table being shown to the user. In such cases it is required that > the encoded page number parameter should be set to the second last page. The > simplest way to take care of this is to do the following in your JSP page ( > using scriptlet or JSTL ) : > if((recordCount % 10 == 0) && !code.equals("coursemap.delete.required")) { > Enumeration names = session.getAttributeNames(); > while(names.hasMoreElements()) { > String name = (String)names.nextElement(); > if((name.startsWith("d-") && name.endsWith("-p")) || > (name.startsWith("z-") && name.endsWith("-p"))) { > int value = > ((Integer)session.getAttribute(name)).intValue(); > if(value > 1) { > session.setAttribute(name, new > Integer(value-1)); > } else { > session.removeAttribute(name); > } > } > } > } > Summary: > This is really not a great solution because we modified the existing display > tag code to make it session-aware. Ideally, there should be an attribute > defined in the <display:table> tag which should specify whether user wants > Pagination/Sorting function to be session-enabled or not. Also it should > provide some simpler way to get to know the name of the session attribute > which stores the sort order, current page number, sort column index, so that > a user doesnt need to iterate over the session attributes to remove it. -- This message is automatically generated by JIRA. - If you think it was sent incorrectly contact one of the administrators: http://jira.codehaus.org/secure/Administrators.jspa - For more information on JIRA, see: http://www.atlassian.com/software/jira ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ displaytag-devel mailing list displaytag-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/displaytag-devel