z3c.form add fields dynamically an catalog.results

236 views Asked by At

How can I dynamically add form fields, depending on catalog.results?

For Example:

catalog.results = ['Channel A', 'Channel B', 'Channel C',]

form.fields should be

form.fieldset Channels A {
  input[type=checkbox].course a1
  input[type=checkbox].course a2
  input[type=checkbox].course a3
}
form.fieldset Channels B {
  input[type=checkbox].course b1
  input[type=checkbox].course b2
  input[type=checkbox].course b2
}

Every Channel is folderish, and every Channel can contain N courses, for each channel should be a fieldset and for every cours should be a input[type=checkbox](Or MultiCheckbox) Field generated

Sorry, I updated my question, because our designer send a wrong Image

1

There are 1 answers

1
Mathias On

I would no recommend create a separate field for every option.

You can define a list field in your z3c.form with the CheckBoxFieldWidget:

from zope import schema
from plone.directives import form
from z3c.form.browser.checkbox import CheckBoxFieldWidget


class IChannels(form.Schema)

    form.widget(channels=CheckBoxFieldWidget)
    channels = schema.List(
        title=_(u'label_channels', default='Channels'),
        value_type=schema.Choice(
            vocabulary=u'channels.vocabulary'),
        required=False)

Now register a vobaulary, name channels.vocabulary, which returns terms based on a catalog query.

from zope.interface import directlyProvides
from zope.schema import vocabulary
from zope.schema.interfaces import IVocabularyFactory


def channels_vocabulary(context):
    catalog = getToolByName(context, 'portal_catalog')
    terms = []
    query = {}  # Your query
    for term in catalog(**query):
        terms.append(vocabulary.SimpleTerm(value=term.decode('utf8'),
                                token=normalizer.normalize(term.decode('utf8')),
                                title=term.decode('utf8')))
    return vocabulary.SimpleVocabulary(terms)

directlyProvides(channels_vocabulary, IVocabularyFactory)

Register with zcml:

<utility
  component=".vocabularies.channels_vocabulary"
  name="channels.vocabulary"
/>

The example is based on http://docs.plone.org/develop/plone/forms/schemas.html#multi-choice-example