[ http://jira.codehaus.org/browse/DISPL-263?page=comments#action_73886 ] Marianne Lund commented on DISPL-263: -------------------------------------
I disagree with the priority level on this bug - in many cases you wish to come back to the same page not having to redo sorting or paging. I think that displaytag should be user friendly also in applications of some complexity. When can I see this functionality added into a standard release? > 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 ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ displaytag-devel mailing list displaytag-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/displaytag-devel