[Seaside] tables

Cees de Groot cg at cdegroot.com
Sat Mar 22 11:34:53 CET 2003


On Sat, 2003-03-22 at 05:15, Nevin Pratt wrote:
> Does anybody else find tables rather clutsy to deal with?  For example...
> 
Yes. But remember that tables are complex beasts in any case. They are
clumsy to deal with in TeX, in SGML, ...., so we're in good company here
:-)

> Now when you combine the above code with multiple #tableRows: and 
> #tableData: methods for a more sophisticated table, you get quite a 
> clump of unintelligable "mashed potato code". 

For simple tables, like the basic two-colum table that comprises an
input form, refactoring the html generator is the solution - Avy shown
#tableRowWith:with:, but you could go a step further and have the html
generator do The Right Thing with:

html standardForm: [html
   prompt: foo field: bar;
   prompt: foo field: bar]

(where 'field: bar' stands for various permutations of generating input
fields with action blocks, etcetera). #standardForm: could combine #form
and #table, and #prompt#field: combines #tableRow:, #tableData:, and the
various input generation thingies. 

Remember, Seaside is young, there's limited 'real-world' experience, so
any feedback on extensions like these is quite likely to flow back into
Seaside at this point. What you've got at the moment is bare-bones...

> Anyway, I wish I had something more constructive to offer here, like an 
> elegant solution or something, instead of just complaining.
> 
Another solution I pursued around a year ago (totally not
seaside-related, but I think I could integrate it), for more complex
tables, is to describe the table with metadata and then hand it a
collection. This is useful for somewhat larger tables, e.g. for
on-screen reports. Lemmeesee whether I can find the code...

   tableGen := TableGenerator new.
   tableGen 
     sortColumn: 2;
     sortOrder: #descending;
     columns: (OrderedCollection new
      add: (Array 
          with: (#domainname << #transfer >> 'Domainname') 
          with: [:context | context domain name]);
      add: (Array 
          with: (#transferDate << #transfer >> 'Date') 
          with: [:context | context requestDate]);
      add: (Array 
          with: (#newOwner << #transfer >> 'New owner') 
          with: [:context | context newOwner displayName]);
      yourself
   tableGen generatorFor: transfers using: html.

I think that's the one. The problem is, we have so many UI experiments
lying around (finally converging on seaside-like generation now ;-))
that it might well be the wrong one. Note that the #foo << #bar >> 'baz'
thingies is VW speak for UserMessages, we have a completely
internationalized interface.

Browsing further, I also see a couple of more heavy-weight components -
a TableView (one of our - failed - UI experiments is to stick with
strict MVC, we're now combining VC into 'Component'...). It displays a
TableModel which holds stuff like the collection to display, heading
labels, and does neat things like alternating the background colors for
the rows and putting up/down arrows near the column headings so you can
re-sort the table on every column; if you want to, it also puts 'delete'
and 'edit' icons at the start of every row, in case the table rows
represent things that you want to be able to remove from its parent
collection or edit. It does require some cooperation on the side of the
objects displayed - business objects we display know either how to act
as TableRow objects or know how to create these from themselves.

Using it in our environment is mostly a matter of feeding the TableModel
all the data - collection to display, column headers, sort blocks - and
feeding that to our TableView. The latter class has a horrendously
complex rendering method (30 lines of code), but the users of the class
usually are a handful of lines of (clean) code.

Personally, I'm a big fan of letting domain objects help out in
constructing their user interfaces. We hardly ever need to go through
long and tedious #renderOn: methods, because we farm out a lot of the
work to the objects displayed. 

An unrelated example is that at the moment, we're changing the UI to be
comprised of what we call 'Browsers', high-level components that control
a logically related set of domain objects - in our ISP setting, we have
a customer browser (actually a Party browser), a domain browser, a
finance browser, etcetera. All objects displayed need to be able to spit
out a link (with caption) to a browser that will open on them; the idea
is that we use these links all over the place, and when you switch
browsers (moving from one 'logical domain' in the application to another
by following these links), a 'breadcrumbs' trail is built up on top.
Without help of the domain objects, this'd be undoable.  


-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
Url : http://lnx-12.ams-2.theinternetone.net/pipermail/seaside/attachments/20030322/5334dc40/attachment.bin


More information about the Seaside mailing list