I have uploaded my version of the tacos source (svn trunk at around noon on May 5, 2006) with the tacos:Grid component included. However, I haven't completed updating the build.xml file or making a demo page, so I will include some instructions here:
- Copy src/js/tacos to the same directory that contains your dojo directory (next to dojo, not in it)
- Copy demo/docroot/js/MochiKit? to the same directory that contains your dojo directory (next to dojo, not in it)
- Use the jar file built by the attached source
- You will have access to a component in the tacos library called Grid
There is no real documentation currently written, so here is a brief overview of the bindings that our app uses to render grids:
- widgetId - This is probably not a correct Tapestry'ism, but this is the id that will be used for the div which will contain the Grid. The id of the tapestry component is used as the dojo widgetId, so this is a particularly poor naming choice.
- columns - an instance of a net.sf.tacos.ajax.components.grid.GridColumnModel?. The GridColumnModel? is really just a container for a collection of GridColumn? objects. This is the first time I am looking at the code, and I would probably have done things differently (like using an ordered Map), but it is what it is. A GridColumn? object describes everything you could want to know about a column, including:
- row property name
- display name
- column width (px, I assume)
- sortable
- dataType (string, date, number, html)
- and a css class to use for each cell in this column that isn't a header or footer
- source - this should be either a collection of beans or a collection of maps. Either one will work. The 'name' specified in the GridColumn? is either the property of the bean or the key of the Map. I believe that there is also an option to specify a TableModel? tpe object (which I think even accepts a contrib:TableModel?), but I have never used it, so it may be buggy
- pageSize, enableMultipleSelect, initialSortOrder, initialSortColumn - should be self evident
- showFilter - a boolean to specify whether the Filter should be visible
- footerRow - a bean or map representing the data for a row that should be displayed at the bottom of every page of the table. I am using it for totals. Eventually, I'd like to be able to specify a 'spec' which describes how the row should be calculated on the client - using avg, sum, column_name, or a specified value
- headerClass, bodyClass, footerClass, rowAlternateClass, containerClass - css class for various components of the table
- headerSortUpClass, headerSortDownClass - a class which is used on the header of any column which is selected and sorted. We use them to change the background of the cell to an up or down arrow
- title - the title of the grid. I can't remember if it is actually rendered in the grid anywhere.
Currently, the tapestry component always writes a reference to a stylesheet called css/grid.css into the document. This should be a specifiable name, of course, but it is also perfectly acceptable to just ignore it and include the necessary style definitions in some other stylesheet included in the page. Now that I think about it, multiple tables would also probably cause the stylesheet to be included multiple times. Oops.
At any rate, here is our css/grid.css file, which renders a table with intentionally ugly colors in order to force the designer to deal with it before our next release:
div.tableContainer { clear: both; border: 1px solid #963; padding: 0px; width: 100%; }
html>body div.tableContainer { width: 100%; }
html>body div.tableContainer table { width: 100%; }
thead.fixedHeader tr { position: relative }
html>body thead.fixedHeader tr { width: 100%; }
thead.fixedHeader th { background: #ccc; font-weight: normal; text-align: left; padding: 2px 2px; }
thead.fixedHeader th.selected { background-color:#fcc; }
thead.fixedHeader a, thead.fixedHeader a:link, thead.fixedHeader a:visited { color: #FFF; display: block; text-decoration: none; width: 100%; }
thead.fixedHeader a:hover { color: #F2F; text-decoration: underline; width: 100%; }
html>body tbody.scrollContent { height: 262px; overflow: visible; width: 100%; }
tbody.scrollContent td, tbody.scrollContent tr td { background: #FFF; border-bottom: none; border-left: none; border-right: 1px solid #CCC; border-top: 1px solid #DDD; padding: 2px; }
tbody.scrollContent tr.alternateRow td { background: #EDE; border-bottom: none; border-left: none; border-right: 1px solid #CCC; border-top: 1px solid #DDD; padding: 2px; }
tbody.scrollContent tr.selected td { background: yellow; border-bottom: none; border-left: none; border-right: 1px solid #CCC; border-top: 1px solid #DDD; padding: 2px; }
tbody.scrollContent tr:hover td { background: #cfc; border-bottom: none; border-left: none; border-right: 1px solid #CCC; border-top: 1px solid #DDD; padding: 2px; }
tbody.scrollContent tr.selected:hover td { background: #ff3; border-bottom: none; border-left: none; border-right: 1px solid #CCC; border-top: 1px solid #DDD; padding: 2px; }
table.tablecontainer{ width: 100%; }
.headerSortUp { background: #FDE; background-image: url(/reporting/img/down.gif); background-repeat: no-repeat; background-position: right center; }
.headerSortDown { background: #EDE; background-image: url(/reporting/img/up.gif); background-repeat: no-repeat; background-position: right center; }
.fixedFooter { text-align: right; font-weight: bold; background: #DA8;}
.dateClass,.dateClassSelected { text-align: left; background: #FCA;}
.textClass,.textClassSelected { text-align: left; background: #FCA;}
.currencyClass,.currencyClassSelected { text-align: right; background: #FCA;}
.numberClass,.numberClassSelected { text-align: right; background: #FCA;}
I have also attached a .page file containing a reference to a single Grid component.
leonardo@dtqsoftware.com said, 05/05/2006:
We could use "containerId" instead of "widgetId" don't you think?