E-Mail Form: Hide Fields conditional to value of Configuration Registry entry

I created a mail form within a Plone add-on which contains some fields which should only displayed (and used), if an entry in the controlpanel and the Configuration Registry has the value '1'. If this value is '0' the fields should be hidden. They should also not get into the e-mail which will be send out.

I had the following field in the controlpanel.py:

conferencefee = schema.Choice(
    title=_(safe_unicode('Registration Fee?')),
    description=_(safe_unicode('Have one to pay a registration fee?')),
    vocabulary=yesnochoice,
    required=True,
)

The vocabulary is imported from another module and looks like this:

yesnochoice = SimpleVocabulary(
[SimpleTerm(value=0, title=(u'No')),
SimpleTerm(value=1, title=
(u'Yes'))],
)

Thus if the user choose 'No', the value inside the Config Registry gets an int 0 and if 'Yes' it is int 1.

I tried to use the value from the Config Registry with 'api.portal.get_registry_record('collectiveconference.conferencefee') inside the conference registration form to control, if some fields are displayed or hidden. But that didn't work so far.

I had a class RegistrationMailSchema(interface.Interface) with the field:

paymentway = schema.List(
    title=_(safe_unicode('Way of Registration Fee Payment')),
    description=_(safe_unicode(
        'If you already payed the registration fee, please tell us, which way you used to transfer the   money.')),
    value_type=schema.Choice(source='PaymentOptions'),
    required=False,
)

Then the adapter class class RegistrationAdapter(object) with the function:

def __init__(self, context):
    (...)
    self.paymentway = None

And then the class:

class RegistrationForm(AutoExtensibleForm, form.Form):
schema = RegistrationMailSchema
form_name = 'registrationmail_form'

label = _(safe_unicode('Mail To The Conference Organizer'))
description = _(safe_unicode('Register for the conference.'))

fields = field.Fields(RegistrationMailSchema, IReCaptchaForm)
fields['captcha'].widgetFactory = ReCaptchaFieldWidget
fields['paymentway'].widgetFactory = RadioFieldWidget

I want to hide the fields 'paymentway' depending on the value in the Config Registry for 'conferencefee'.

I could test the value of the Config Registry entry inside the (later in the registration form created) handleApply function and print depending on this value a specific string. But I couldn't use this if clause to control, if a field is displayed or hidden.

Thanks for any hints in advance.

Please see this discussion on a similar question a few months ago:

Also, maybe schema.Bool is simpler for this field, but you might have less control over the display values (yes/no), depending on the widget you set on a Boolean field.

Hi Fred,

thanks for your hint.

I tried it with adding if clauses to the update method:

class RegistrationForm(AutoExtensibleForm, form.Form):
    schema = RegistrationMailSchema
    form_name = 'registrationmail_form' label = _(safe_unicode('Mail To The Conference Organizer'))
    description = _(safe_unicode('Register for the conference.'))

    fields = field.Fields(RegistrationMailSchema, IReCaptchaForm)
    fields['captcha'].widgetFactory = ReCaptchaFieldWidget
    fields['paymentway'].widgetFactory = RadioFieldWidget

    def update(self):
        # disable Plone's editable border self.request.set('disable_border', True)
        if api.portal.get_registry_record('collectiveconference.conferencefee') == 0:
            RegistrationForm.fields['registrationpayed'].mode = 'hidden' RegistrationForm.fields['paymentway'].mode = 'hidden' RegistrationForm.fields['usedbank'].mode = 'hidden' super(RegistrationForm, self).updateWidgets()

        # call the base class version - this is very important! super(RegistrationForm, self).update()
        if api.portal.get_registry_record('collectiveconference.conferencefee') == 0:
            RegistrationForm.fields['registrationpayed'].mode = 'hidden' RegistrationForm.fields['paymentway'].mode = 'hidden' RegistrationForm.fields['usedbank'].mode = 'hidden' super(RegistrationForm, self).updateWidgets()

This works, if I change the entry in the Configuration Registry from yes (1) to No (0). But if I change back to yes (1), the fields are not visible again. If I restart Plone afterwards, the fields are displayed (and editable) again.

I tried this several times with the same result.
I run Plone in foreground mode (fg).

I added also an entry to configure.zcml but that didn't change Plone's behavior:


<browser:page
    name="edit"
    for="collective.conferences.registrationform.RegistrationAdapter"
    layer="collective.conferences.interfaces.ICollectiveConferencesLayer"
    class=".registrationform.RegistrationForm"
    permission="zope2.View"
    />

Regards,
Andreas

Slightly off topic, but in case it can be of any interest:

It is possible to read a value from the registry in the theme's manifest file

So, in yourtheme/manifest.cfg

fullmenu =  python:context.portal_registry['my.theme.interfaces.IMyThemeSettings.rules']=='fullmenu'

cssfile =   python:context.portal_registry['my.theme.interfaces.IMyThemeSettings.style']

Then in rules.xml

  <rules if="$fullmenu">
       <xi:include href="++theme++mytheme/fullmenu.xml"/>
  </rules>

Of course, the same approach can be used for CSS, something like:

  <rules if="$fullmenu">
    <link  rel="stylesheet" href="++theme++mytheme/css/{$cssfile}.css"/>
  </rules>

UPDATE: the part with css needs to be in a rule, maybe

  <after css:theme="body"

Plone Foundation Code of Conduct