[
http://jira.codehaus.org/browse/DISPL-263?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
fabrizio giustina closed DISPL-263.
-----------------------------------
Resolution: Fixed
Fix Version/s: (was: TBD)
1.1.2
Closing as a duplicate of DISPL-125
stay tuned, this feature will soon be released as part of displaytag 1.1.2 ;)
> 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: 1.1.2
>
> 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
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
displaytag-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/displaytag-devel