[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 = []
else:
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 = []
try:
for val in values:
int_values.append(int(val))
except ValueError:
raise InputError("%s contains an invalid choice." % str(values))
if self.choicesAttribute is not None:
choices = getattr(binding, self.choicesAttribute)
else:
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)
else:
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),
tv.choicesAttribute)
else:
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:
selecter[option(value=str(index),
selected="selected")[stringify(val)]]
else:
selecter[option(value=str(index))[stringify(val)]]
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,
iformless.ITypedRenderer)
compy.registerAdapter(MultipleChoiceInputProcessor, MultipleChoice,
iformless.IInputProcessor)
compy.registerAdapter(MultipleChoiceRenderer, Sites, iformless.ITypedRenderer)
compy.registerAdapter(MultipleChoiceInputProcessor, Sites,
iformless.IInputProcessor)
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