Table support

Rendering tables using Albatross Forms is relatively straightforward, using them for input is no harder.

Table support revolves around two classes: IteratorTable and IteratorTableRow.

IteratorTable acts as a field in a form where it renders the table.

IteratorTableRow should be subclassed within the application to render each row in turn.

Here's an example which should render a list of name, address and phone numbers in a table. First we define the model object:

   1 class Entry:
   2     def __init__(self, name, address, phone);
   3         self.name = name
   4         self.address = address
   5         self.phone = phone

Now we'll define the components of the form to render a list of Entry instances.

   1 class EntryTableRow(IteratorTableRow):
   2 
   3     def __init__(self, entry):
   4         cols = (
   5             Col((TextField('Name', 'name'), )),
   6             Col((TextField('Address', 'address'), )),
   7             Col((TextField('Phone', 'phone'), )),
   8         )
   9         IteratorTableRow.__init__(self, cols)
  10         
  11         self.load(invoice_header)
  12 
  13 
  14 class EntryTableForm(Form):
  15     def __init__(self, entries):
  16         headers = Row((
  17             HeaderCol((Label('Name'), )),
  18             HeaderCol((Label('Address'), )),
  19             HeaderCol((Label('Phone'), )),
  20         ))
  21         self.table = IteratorTable('table', headers, EntryTableRow, entries,
  22                                    html_attrs={'width': '100%'})
  23         Form.__init__(self, 'Address book', (self.table, ))

To create the form:

   1 def page_enter(ctx):
   2     entries = ((
   3         Entry('Ben Golding', 'Object Craft, 123/100 Elizabeth St, Melbourne Vic 3000', '+61 3 9654-9099'),
   4         Entry('Dave Cole', 'Object Craft, 123/100 Elizabeth St, Melbourne Vic 3000', '+61 3 9654-9099'),
   5     ))
   6     if not ctx.has_value('entry_table_form'):
   7         ctx.locals.entry_table_form = EntryTableForm(entries)
   8         ctx.add_session_vars('entry_table_form')

Rendering the list just requires:

<al-form method="post">

  <div class="alxform">
    <alx-form name="entry_table_form" static />
  </div>

</al-form>

To support editing the fields, you would change how it renders using:

<al-form method="post">

  <div class="alxform">
    <alx-form name="entry_table_form" errors />
  </div>

</al-form>

When the user has made changes, your page_process method can pick up the changes using:

   1 def page_process(ctx):
   2     if ctx.req_equals('save'):
   3         ctx.locals.entry_table_form.merge(ctx.locals.entries)
   4         save(ctx.locals.entries)