I have a z3c.form that's used during registration. One of the fields is a list of emails users may wish to sign up for.
from zope import schema
from zope.schema.vocabulary import SimpleVocabulary
emailVocab = SimpleVocabulary.fromItems((
('sysn', u'System notifications (strongly recommended)'),
('mark', u'Marketing emails'),
('offe', u'Special offers')))
...
email_optin = schema.List(
title = u'',
description = u'',
required = False,
value_type = schema.Choice(source=emailVocab))
I'd like to have the first of these to be selected by default, while the others should not be. I can't see a way in the spec to do this. Any ideas?
Simplest case is as documented in Modelling using zope.schema, default value section, which
z3c.formpicks up (relevant documentation). However, this is complicated by the fact that the default values should not be mutable as the instance is shared across everything, so for safety sake adefaultFactoryargument is implemented for handling this. Putting all that together, you should have something like this:Do note that the actual value used for the default is not the
tokenpart but thevaluepart, hence the string'Special offers'is returned instead of'offe'. It is documented in the documentation about Vocabularies. If the human readable part is intended to be the title and you wish the actual value to be the same as the token you will need to adjust your code accordingly. Otherwise, to select the first one you simply havedefault_emailreturn[u'System notifications (strongly recommended)'].For completeness, your form module might look something like this:
Alternatively, you can use value discriminators to approach this issue if you don't wish to populate the interface with a default value or factory for that, but this is a lot more effort to set up so I generally avoid dealing with that when this is good enough.