r1 - 27 Dec 2005 - 07:16:17 - SooGuanYou are here: TWiki >  Main Web  >  ElixirReport > ElixirReportCookbook > PageTotal

Modify Page Numbering behavior

Not happy with ${#} and ${##}? Then do it yourself with scripts...

In order to know the total page count you need to wait until all pages have been rendered. You then need to go back and insert the values. Here's a general technique for doing that by building a list of callback functions and then executing it at the end of rendering.

Report:On Render Begin
pageCount = 0;
pageFooters = new java.util.ArrayList();

Field():On Render End // this is the page count literal field
function fn(t,pageNo,pageTotal)
{
  t.setText("Page "+pageNo+" of "+pageTotal);
}
fn.target = result.getLogicalElement(0);
pageFooters.add(fn);
++pageCount;

Report:On Render End
i = 1;
it = pageFooters.iterator();
while (it.hasNext())
{
  fn = it.next();
  fn(fn.target,i,pageCount);
  ++i;
}
At the beginning (Report onRenderBegin) we initialize the pageCount to 0 and create an empty list for holding the functions.

Each time we hit the field (in the page footer in this case) that should show the page info, we define a function to do the job and store it in the list. We then increment the pageCount (this would be in a different script if the field were not in the page footer).

Finally, when we get to the end (Report onRenderEnd) we iterate through the list getting each function, and call it with the appropriate parameters. Of course the text fields must be wide enough to hold the text (I suggest putting a literal like "Page 999 of 999" as the default value, because if you leave it empty there's nothing to render and you won't get a text element in the result to write over) because the wrapping and pagination has already been done before this substitution.

Note that fn.target is not a special name, you can add attributes on the fly to any JavaScript object, including functions.

Now you can do any kind of formatting of the numbers because the whole thing is in JavaScript.

Of course you can generalize this mechanism to any sort of post-processing - "reverse hide duplicates" which hides all but the last value, putting page totals in page headers, etc. etc.

I'm naming this concept "temporal scripts" - scripts whose execution can be delayed to arbitrary points - eg. OnGroupEnd?, OnPageEnd?, OnSectionEnd?, OnReportEnd?. I was originally planning to add explicit support for temporal scripts, but it is simple enough in plain JavaScript and much more extensible than me forcing a specific function signature for everyone to follow.

-- SooGuan - 27 Dec 2005

Edit | Attach | Printable | Raw View | Backlinks: Web, All Webs | History: r1 | More topic actions
 
Powered by TWiki
This site is powered by the TWiki collaboration platformCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback