If you want to do anything fancy with the form,  you may be better to
use SQLFORM. It is also convenient to use and gives more flexibility.

If you want to do any helpful processing on the client-side, you
should try javascript,  see Ajax Recipes in the book.

On May 13, 5:10 pm, "ma...@rockiger.com" <rocki...@googlemail.com>
wrote:
> What is the most elegant solution to this problem:
>
> I have a form for address information in an ecommerce application.
> The user can optionally input a different delivery address - this is done
> via radio button.
> In this case the requirement for the delivery address fields change -
> nothing special actually.
>
> What I've done so far:
>
> Model:
>
> db.define_table('customer',
>    Field('name', requires=[IS_NOT_EMPTY()], required=True, notnull=True),
>    Field('company',default=None),  
>    Field('zip', requires=[IS_MATCH('^[0-9]{5}$', error_message='not a zip
> code')], required=True, notnull=True),
>    Field('street', requires=[IS_MATCH("[0-9a-zA-ZäöüÄÖÜ\- \.]+")],
> required=True, notnull=True),
>    Field('city', requires=[IS_MATCH("[a-zA-ZäöüÄÖÜ\- \.]+")], required=True,
> notnull=True),
>    Field('country', requires=[IS_IN_SET([T('Deutschland'),T('Östereich'),
> T("Schweiz")])], default="Deutschland"),
>    Field('email',requires= [IS_NOT_EMPTY(), IS_EMAIL(),
>    IS_NOT_IN_DB(db,'customer.email')],
>    required=True, notnull=True),
>    Field('email_confirmation',requires= [IS_NOT_EMPTY(), IS_EMAIL(),
>    IS_NOT_IN_DB(db,'customer.email')],
>    required=True, notnull=True),
>    Field('delivery_address',
> requires=[IS_IN_SET([T('Yes'),T('No')])],widget=SQLFORM.widgets.radio.widget,
>  default="No"),
>    Field('delivery_name',default=None),
>    Field('delivery_company',default=None),
>    Field('delivery_zip', requires=[IS_EMPTY_OR(IS_MATCH('^[0-9]{0,5}$',
>  error_message='not a zip code'))]),
>    Field('delivery_street', requires=[IS_EMPTY_OR(IS_MATCH("[a-zA-ZäöüÄÖ\-
> \.]+"))],default=None),
>    Field('delivery_city', requires=[IS_EMPTY_OR(IS_MATCH("[a-zA-ZäöüÄÖ\-
> \.]+"))],default=None),
>    Field('delivery_country',
> requires=[IS_EMPTY_OR(IS_IN_SET([T('Deutschland'),T('Östereich'),
> T("Schweiz")]))],  default="Deutschland"),
>    Field('timestamp', 'datetime', default=request.now, readable=False,
> writable=False)
> )
>
> controller:
>
> def address():
>    crud.messages.submit_button = 'Weiter zur Bestätigungsseite'
>    crud.settings.formstyle='table2cols'
>    form = crud.create(db.customer)
>    if form.accepts(request.vars, session, onvalidation=__address_validator):
>    response.flash = 'form accepted'
>    return dict(form=form)
>
> def __address_validator(form):
>    if not form.vars.email == form.vars.email_confirmation:
>        form.errors.email_confirmation = "Email-Adressen stimmen nicht
> überein."
>    if form.vars.delivery_address == T("Yes"):
>       if not form.vars.delivery_name:
>          form.errors.delivery_name = "Bitte gib einen Namen ein."
>       if not form.vars.delivery_zip:
>          form.errors.delivery_zip = "Bitte gib eine Postleitzahl ein."
>       if not form.vars.delivery_street:
>          form.errors.delivery_street = "Bitte gib eine Straße mit Hausnummer
> ein."
>       if not form.vars.delivery_city:
>          form.errors.delivery_city = "Bitte gib eine Stadt ein."
>       if not form.vars.delivery_country:
>          form.errors.delivery_name = "Bitte gib ein Land an."
>
> This works! But it is not very nice to the user, because the check of the
> optional fields happens after the form is accepted.
> Is there a better way to set the requirements for the optional fields?
>
> Thanks for help

Reply via email to