[Twisted-web] Multiple choices

Justin Johnson justinjohnson at gmail.com
Mon May 17 09:15:02 MDT 2004

Here's an example of what I did to get a multiple choice select box. 
It's been a while since I did this so it could probably use some
cleanup.  But it is working for me.

class MultipleChoice(formless.Typed):
    """Allow the user to pick from a list of "choices", or a list of
choices found
    by accessing the list in the attribute "choicesAttribute" of the object we
    are configuring. The elements of the list will be rendered by calling the 
    function passed to stringify, which is by default "str".
    def __init__(self, choices=None, choicesAttribute=None,
stringify=str, *args, **kw):
        formless.Typed.__init__(self, *args, **kw)
        if choices is None:
            self.choices = []
            self.choices = choices
        self.choicesAttribute = choicesAttribute
        self.stringify = stringify

    def coerceWithBinding(self, values, binding):
        """Coerce a value with the help of an object, which is the object
        we are configuring.
        int_values = []
            for val in values:
        except ValueError:
            raise InputError("%s contains an invalid choice." % str(values))
        if self.choicesAttribute is not None:
            choices = getattr(binding, self.choicesAttribute)
            choices = self.choices
        return [choices[val] for val in int_values]

class MultipleChoiceInputProcessor(compy.Adapter):
    __implements__ = iformless.IInputProcessor,

    def process(self, context, boundTo, data):
        """data is a list of strings at this point
        typed = self.original

        if data[0] == '':
            if typed.required:
                raise InputError(typed.requiredFailMessage)
                return []
        elif hasattr(typed, 'coerceWithBinding'):
            return typed.coerceWithBinding(data, boundTo)
        return typed.coerce(data)

class MultipleChoiceRenderer(webform.BaseInputRenderer):
    def input(self, context, slot, data, name, value):
        tv = data.typedValue
        if tv.choicesAttribute:
            choices = getattr(context.locate(formless.IConfigurable),
            choices = tv.choices

        numChoices = len(choices)
        if numChoices == 0:
            return None

        selecter = select(name=name, size=min(5,numChoices), multiple=1)
        stringify = tv.stringify

        for index, val in enumerate(choices):
            if val == value:
        return slot[selecter]

class Sites(MultipleChoice):
    def __init__(self, choices=None, choicesAttribute=None,
stringify=str, *args, **kw):
        choices = SITES  # SITES is a list of strings
        MultipleChoice.__init__(self, choices, choicesAttribute,
stringify, *args, **kw)
        self.requiredFailMessage = "Please select at least one site."

compy.registerAdapter(MultipleChoiceRenderer, MultipleChoice,
compy.registerAdapter(MultipleChoiceInputProcessor, MultipleChoice,

compy.registerAdapter(MultipleChoiceRenderer, Sites, iformless.ITypedRenderer)
compy.registerAdapter(MultipleChoiceInputProcessor, Sites,

On Mon, 17 May 2004 10:11:19 -0400, Donovan Preston <dp at ulaluma.com> wrote:
> On May 17, 2004, at 9:41 AM, vicky wrote:
> >          I'm working on forms with nevow. I would like to know if it's
> > possible to use multiple choices with ChoiceRenderer. I noticed that
> > the
> > multiple choices are not available because the class ProcessTyped
> > return
> > data[0] and not the complete list data. I know that I could create my
> > own
> > classes and functions but I wanted to know if it was already possible
> > to do
> > it.
> No, currently there are no implementations of a multiple choice ui and
> form handling, I just haven't had the need for it. Patches would be
> welcome.
> dp
> _______________________________________________
> Twisted-web mailing list
> Twisted-web at twistedmatrix.com
> http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web

More information about the Twisted-web mailing list