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 == '': 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 email@example.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 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.
Twisted-web mailing list Twistedfirstname.lastname@example.org http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web