4.2 Using Albatross Input Tags (Again)

In the previous chapter we demonstrated the use of Albatross input tags to transfer values from the execution context into HTML <input> tags, and from the browser request back into the execution context. In this section we present the same process using an Albatross application object.

The sample program from this section is supplied in the samples/form4 directory and can be installed in your web server cgi-bin directory by running the following commands.

cd samples/form4
python install.py

The form.html template file used by the application follows.

<html>
 <head>
  <title>Display Form Input</title>
 </head>
 <body>
  Input some values to the following form and press the submit button.
  <al-form method="post">
   Text field: <al-input name="text"><br>
   Singleton checkbox: <al-input type="checkbox" name="singleton"><br>
   Checkbox group:
   <al-input type="checkbox" name="group" list value="check1">
   <al-input type="checkbox" name="group" list value="check2"><br>
   Radio buttons:
   <al-input type="radio" name="radio" value="radio1">
   <al-input type="radio" name="radio" value="radio2"><br>
   Option menu:
   <al-select name="select">
    <al-option>option1</al-option>
    <al-option>option2</al-option>
    <al-option>option3</al-option>
   </al-select>
   <al-input type="submit" name="submit" value="submit">
  </al-form>
  number of requests: <al-value expr="num"><br>
  text: <al-value expr="text"><br>
  singleton: <al-value expr="singleton"><br>
  group: <al-value expr="group"><br>
  radio: <al-value expr="radio"><br>
  select: <al-value expr="select"><br>
 </body>
</html>

The most important new features in the template file are the use of the <al-form> tag, and the list attribute in the <al-input type="checkbox"> tag.

Most execution contexts created by application objects inherit from the NameRecorderMixin. The NameRecorderMixin records the name, type and multiple value disposition of each input tag in a form in a hidden field named __albform__. The recording process requires that all <al-input> tags be enclosed by an <al-form> tag.

Any input field with the list attribute will always receive a list value from a POST browser request regardless of how many values (including none) were sent by the browser. An exception will be raised if you specify multiple input tags with the same name in a form and do not include the list attribute. The input tag types radio, image, and submit are implicitly flagged to receive multiple values so the list attribute must not be specified on these.

The form.py program is show below.

#!/usr/bin/python
from albatross import SimpleApp
from albatross.cgiapp import Request

class Form:

    def page_enter(self, ctx):
        ctx.locals.text = ctx.locals.singleton = ctx.locals.group = \
                          ctx.locals.radio = ctx.locals.select = None
        ctx.locals.num = 0
        ctx.add_session_vars('num')

    def page_display(self, ctx):
        ctx.locals.num += 1
        ctx.run_template('form.html')

app = SimpleApp(base_url = 'form.py',
                template_path = '.',
                start_page = 'form',
                secret = '-=-secret-=-')
app.register_page('form', Form())

if __name__ == '__main__':
    app.run(Request())

You can run the program by pointing your browser at http://www.object-craft.com.au/cgi-bin/alsamp/form4/form.py.

Notice that the browser request is automatically merged into the local namespace and then extracted by the template when generating the HTML response.

The program uses the SimpleApp application class. SimpleApp uses an object to define each page served by the application. Each of the page objects must be registered with the application via the register_page() method.

When the application enters a new page SimpleApp calls the page_enter() method of the page object to allow the application to initialise execution context values. In the above program the page_enter() method initialises all values used by the HTML form to None, initialises the variable num to 0 and places it into the session.

As shown in the application processing sequence on page , the first step in handling a browser request is to create an execution context. The SimpleApp class uses instances of the SimpleAppContext class which inherits from HiddenFieldSessionMixin. The HiddenFieldSessionMixin class stores session data in a hidden field named __albstate__ at the end of each form.

When an Albatross application needs to display the result of processing a request it calls the page_display() method of the current page. In the above program this method increments num and then runs the form.html template. It is important to note that any changes to session values after executing a template will be lost as the session state is saved in the HTML produced by the template.

It is worth explaining again that the program does not perform any request merging -- this is all done automatically by the Albatross application and execution context objects.