4. Creating a Table Using ZenTableManager

ZenTableManager is a Zope product that helps manage and display large sets of tabular data. It allows for column sorting, breaking down the set into pages, and filtering of elements in the table.

Here's a sample of a table listing all devices under the current object along with their IPs. First we set up the form that will deal with our navigation form elements:


...
<form method="post" tal:attributes="action here/absolute_url_path" name="[MYFORM]">
script type="text/javascript" src="/zport/portal_skins/zenmodel/submitViaEnter.js"></script>

Next, we set up our table, defining the objects we want to list (in this case, here/devices/getSubDevicesGen). We then pass those objects, along with a unique tableName, to ZenTableManager, which will return a batch of those objects of the right size (for paging purposes):


<table class="zentable"
tal:define="objects here/devices/getSubDevicesGen;
tableName string:myDeviceTable;
batch python:here.ZenTableManager.getBatch(tableName, objects)"
tal:condition="python:batch or
here.ZenTableManager.getTableState(tableName, 'filter')">

Next, a table header and a couple of hidden fields:


<tr>
<th class="tabletitle" colspan="2"> <!--Colspan will of course change with the number of fields you show-->
My Devices
</th>
</tr>
<input type='hidden' name='tableName' tal:attributes='value tableName' />
<input type='hidden' name='zenScreenName' tal:attributes='value template/id' />

Now we add the rows that describe our devices. First we need to set up the column headers so that they'll be clickable for sorting. For that, we use ZenTableManager.getTableHeader(tableName, fieldName, fieldTitle, sortRule="cmp").


<tbody>
<tr>
<!--We want to sort by names using case-insensitive comparison-->
<th tal:replace="structure python:here.ZenTableManager.getTableHeader(
tableName, 'primarySortKey', 'Name', 'nocase')">name</th>
<!--Default sortRule is fine for IP sorting-->
<th tal:replace="structure python:here.ZenTableManager.getTableHeader(
tableName, 'getDeviceIp', 'IP')">ip</th>
</tr>

Now the data themselves. In order to have our rows alternate colors, we'll use the useful TALES attribute "odd", which is True for every other item in a tal:repeat.


<tal:block tal:repeat="device batch">
<tr tal:define="odd repeat/device/odd"
tal:attributes="class python:test(odd, 'odd', 'even')">
<td class="tablevalues">
<a class="tablevalues" href="href"
tal:attributes="href device/getDeviceUrl"
tal:content="device/id">device
</a>
</td>
<td class="tablevalues"
tal:content="device/getDeviceIp">ip</td>
</tr>
</tal:block>
</tbody>

Finally, let's add the navigation tools we need and close off our tags.


<tr>
<td colspan="2" class="tableheader">
<span metal:use-macro="here/zenTableNavigation/macros/navbodypagedevice" />
</td>
</tr>

</table>
</form>