Minor enhancements to the XPages Table Control
As mentioned in my previous post, I have started up a fork of the ExtLibX project and have started contributing to it instead of my previous GregorbyteXspLibrary. Last week I shared the JDBC Configuration Provider which uses Notes Documents to store the configuration info, within this release was another small contribution with 2 minor enhancements for the XPages table control.
The core XPages table control does not provide support for thead, tbody, and tfoot elements. Also there isn’t an option for a th control.
There are some easy workarounds for this such as just using passthrough html as Chris Toohey demonstrated on his blog.
This passthru technique works fine but I just thought I would share my approach, which was to add support for these elements by creating an extra th control, and also extending the table renderer to support use of thead, tfoot and tbody.
It isn’t that exciting but I just thought it was a good example of being able to extend core controls, and add your own desired functionality to them, or modifying existing functionality.
If you would like to try these modifications out, then download the latest release from my camac/ExtLibX project and install to both domino designer and your target domino server.
If you don’t want to install plugins, you should also be able to take the table renderer and th component source code from within this commit and install it to the java, faces-config and xsp-config files in your nsf
Using the Table Header Cell control
To use a th Cell, simply use the Table Header Cell control. It is exactly like a normal <xp:td>
control, except it will render as th instead of td
1 2 3 4 5 |
<xp:tr> <!-- Using the th control --> <xe:th>Last Name</xe:th> <xe:th>First Name</xe:th> </xp:tr> |
Using Table Header, Footer and Body sections
Support for <thead>, <tfoot> and <tbody> elements is provided by an extended version of the Table Renderer, this renderer’s rendererType is: com.ibm.xsp.extlibx.Table.
You have 2 choices on how to enable the table renderer
- Make the renderer default for all tables in the application
- Enable the renderer only for specific tables
Setting Table Renderer for All Tables
You can set the renderer Type for all Tables in your application by including the following in your theme configuration file:
1 2 3 4 5 6 7 |
<control> <name>HtmlTable</name> <property> <name>rendererType</name> <value>com.ibm.xsp.extlibx.Table</value> </property> </control> |
Setting RendererType for a specific table
To enable the renderer for specific tables, just set the rendererType to com.ibm.xsp.extlibx.Table
1 |
<xp:table rendererType="com.ibm.xsp.extlibx.Table"> |
How to specify thead, tfoot and tbody
The thead and tfoot elements can be used by providing a facet named thead or tfoot
The tbody element will be rendered by default and contain all the child elements of the table
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<?xml version="1.0" encoding="UTF-8"?> <xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xe="http://www.ibm.com/xsp/coreex"> <xp:table rendererType="com.ibm.xsp.extlibx.Table"> <!-- thead and tfoot are specified using facets --> <xp:this.facets> <xp:tr xp:key="thead"> <xe:th>Header 1</xe:th> <xe:th>Header 2</xe:th> </xp:tr> <xp:tr xp:key="tfoot"> <xp:td>Footer 1</xp:td> <xp:td>Footer 2</xp:td> </xp:tr> </xp:this.facets> <!-- all the child controls will be automatically renderer within a tbody element --> <xp:tr> <xp:td>R1C1</xp:td> <xp:td>R1C2</xp:td> </xp:tr> <xp:tr> <xp:td>R2C1</xp:td> <xp:td>R2C2</xp:td> </xp:tr> </xp:table> </xp:view> |
Multiple rows within thead / tfoot
Chris Toohey makes a good point in the comments, sometimes you want more than one row in the header or footer. You can achieve this by using a panel as the root component instead of the tr. You can then put multiple tr’s within that panel.
The panel’s <div> tags won’t be rendered unless it has an id. If it has an id and you don’t want the tags rendered you can also use disableOutputTag="false"
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<xp:table> <xp:this.facets> <!-- Multiple rows within tfoot / thead --> <xp:panel xp:key="tfoot"> <xp:tr> <xp:td></xp:td> <xp:td></xp:td> </xp:tr> <xp:tr> <xp:td></xp:td> <xp:td></xp:td> </xp:tr> </xp:panel> </xp:this.facets> </xp:table> |
Let me know what you think. I know this one wasn’t very exciting but I should have some better controls coming out soon! I just did this one because it was quick and easy.
Great stuff – and thanks for the nod!
The only limitation I can see here – and please correct me if I’m wrong – is that you’re limitted to a single row for your thead and tfoot. You May have a use case where you need two rows in the thead, perhaps one that holds a pager control that’s refreshing the contents of the tbody. Just a thought, and something you could easily account for given your approach! (Use an xp:panel as the xp:key container and throw your thead/tfoot rows in accordingly).
Thanks Chris!
Yep you can do more than one row, I have just updated the post with an example of using the panel to contain the rows (same as you suggested)