Handling Multiple Checkboxes

Consider an application like the popview example from the main Albatross documentation. This displays a table with a list of email messages in it. You might want to add a "Delete" checkbox to each message, and a "Delete Selected" button which would allow the user to mark and delete many messages with the one operation. Here is a good way to do that in Albatross.

First, the HTML template creates a form, containing a table with each email message in it, and the Delete Selected button:

<al-form method="post">
        <al-for iter="e" expr="messages">
                    <al-input type="checkbox" name="del_msgs" 
                          valueexpr="e.value().get_message_id()" list>
                <td><al-value expr="e.value().subject()"/></td>
                # .....
        <al-input type="submit" name="delete" value="Delete Selected">

Note that this creates a whole bunch of checkboxes, one for each email message. All these checkboxes have the same name ("del_msgs") but different value (set to the message_id of the respective message). In the page_process() function, all these checkboxes will be represented as a single variable (ctx.locals.del_msgs) which will be a vector containing the value (i.e. the message_id) for all the selected checkboxes.

The "list" attribute to the al-input ensures that it will be a vector, even if no (or 1) checkboxes are selected.

Then, in the page_process function, you can do something like this:

   1 def page_process(self, ctx):
   2     if ctx.req_equals('delete'):  # User pushed the "Delete Selected" button
   3         for id in ctx.locals.del_msgs:
   4             self.mbox.delete_message(id)

What if I want to pre-tick some check boxes?

The page_display function and the template code will do the reverse trick with the context variable when generating the page. I.e. setting ctx.locals.del_msgs[] to a list of the message_ids that the application suggests for deletion, and when the al-input tag is expanded, those specified checkboxes will be checked. You might do that like this:

   1 def page_display(self, ctx):
   2     ctx.locals.del_msgs = []
   3     for m in self.mbox:
   4         if should_be_deleted(m):
   5             ctx.locals.del_msgs.append(m.get_message_id())
   6     ctx.run_template('msglist.html')  

This looks really cool but in fact it's only another instance of Albatross' general handling of form data. If the variable associated with an al-input item is set in the ctx.locals when the page is displayed, then that variable will be copied into the HTML as the default value for that al-input item. Exactly what "default" means depends on what sort of input item it is!

None: Multiple_Checkboxes (last edited 2011-02-15 06:05:18 by localhost)