1.5.4 Putting it together

Let's see how we use all these CherryClasses, variables and methods to build a nice form.

We are going to build a form where users choose a login and a password, enter their e-mail, their country and their hobbies.

We need 6 fields:

Plus we'll add one line between the e-mail field and the country field.

Here is what the code could be:

use Form, MaskTools

# We start by creating a CherryClass that inherits from Form
# This CherryClass will hold all the informations about the form we want to create
CherryClass MyForm(Form):
function:
    def __init__(self):
        # Instantiate all fields plus 3 separators (one at the beginning, one for the line and one at the end)
        headerSep=FormSeparator('', defaultFormMask.defaultHeader)
        login=FormField(label='Login:', name='login', mandatory=1, typ='text')
        password=FormField(label='Password:', name='password', mandatory=1, typ='password')
        password2=FormField(label='Confirm password:', name='password2', mandatory=1, typ='password')
        email=FormField(label='E-mail:', name='email', typ='text', validate=self.validateEmail)
        lineSep=FormSeparator('', self.lineSeparator)
        country=FormField(label='Country:', name='country', typ='select', optionList=['USA', 'Andorra', 'Lichtenstein', 'CherryPyLand'], defaultValue='USA')
        hobbies=FormField(label='Hobbies:', name='hobbies', typ='checkbox', optionList=['Using CherryPy', 'Eating Cherry Pie'])
        submit=FormField(label='', name='Submit', typ='submit')
        footerSep=FormSeparator('', defaultFormMask.defaultFooter)
        self.fieldList=[headerSep, login, password, password2, email, lineSep, country, hobbies, submit, footerSep]

    # Function that checks if an e-mail is correct or not
    def validateEmail(self, email):
        try:
            before, after=email.split('@')
            if not before or after.find('.')==-1: raise 'Error'
        except: return "Wrong email"

    # Function that performs general validation of the form. In our case, we need to check
    # that the passwords match
    def validateFields(self):
        # Warning: paramMap could have no "password" or "password2" key if the user didn't fill out the fields
        if request.paramMap.get('password','')!=request.paramMap.get('password2',''):
            # Set errorMessage for password fields
            self.setFieldErrorMessage('password', 'Not matching')
            self.setFieldErrorMessage('password2', 'Not matching')

mask:
    # Line separator used to draw a line between the email field and the country field
    def lineSeparator(self, label):
        <tr><td colspan=3 height=1 bgColor=black py-eval="maskTools.x()"></td></tr>

view:
    def postForm(self, **kw):
        if self.validateForm():
            return root.formOk()
        else:
            return "<html><body><font color=red>Please correct the errors (fields in red)</font>"+self.formView(1)+"</body></html>"


# Now we just have to create a regular Root CherryClass, that will call some of MyForm's methods
CherryClass Root:
mask:
    def index(self):
        <html><body>
            Welcome, please fill out the form below:
            <py-eval="myForm.formView()">
        </body></html>
    def formOk(self):
        <html><body>
            Thank you for filling out the form.<br>
            All values were correct
        </body></html>

See About this document... for information on suggesting changes.