title: displaytag external paging/sorting and getting true row number
body: <p>I'm using external paging/sorting with a custom TableDecorator and the following DisplayTag table in a JSP:</p>
  
  <pre><code>&lt;display:table id="ixnlist" name="pageScope.itemList" sort="external"
    decorator="org.mdibl.ctd.pwa.displaytag.decorator.IxnTableWrapper"&gt;
  
     &lt;display:column title="Row" property="rowNum" /&gt;
  
     ...more columns...
  &lt;/display:table&gt; 
  </code></pre>
  
  <p>In the table decorator, getListIndex() returns the row number relative only to the current page, not to the overall list (i.e., if we're displaying 100 objects per page, then getListIndex() returns "0" at the top of page 2, not "100").</p>
  
  <pre><code>/**
   * Returns the row number data for the current row.
   *
   * @return String containing row number heading.
   */
  public String getRowNum() {
      final StringBuilder out = new StringBuilder(8);
      out.append(nf.format(getListIndex() + 1))
         .append('.');
      return out.toString();
  }
  </code></pre>
  
  <p>Is it possible in the table decorator to somehow get the row number reflecting the correct offset?  Displaytag <em>is</em> aware of the offset someplace, as it uses it to format the pagination links.</p>
  
  <p>The displaytag docs do not address this question, and the ${row_rowNum} implicit object works identically to getListIndex() in the decorator.</p>
  
  <p>Yes, it's possible to do this by adding a row-number column to the paginated SQL and having the TableDecorator use that if available, but I'd rather not rely on the DAO for that kind of metadata.  The following TableDecorator method takes advantage of a rownum column if it exists, otherwise it uses getListIndex():</p>
  
  <pre><code>/**
   * Returns the row number data for the current row.
   *
   * @return String containing row number heading.
   */
  public String getRowNum() {
      final StringBuilder out = new StringBuilder(8);
      final Map row = (Map) getCurrentRowObject();
  
      // Use 'rnum' column for external pagination if it exists.
      // Kludgy way of doing this.
      if (row.get("rnum") != null) {
          out.append(nf.format(row.get("rnum")));
      } else {
          out.append(nf.format(getListIndex() + 1));
      }
      out.append('.');
      return out.toString();
  }
  </code></pre>
  
  <p>Thanks.</p>
  
  <p>/mcr</p>