Hi, 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. Thank you Vicky
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
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@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@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web
Justin Johnson wrote:
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.
Here's a cleaned up and modernized version, with an example. Please explicitly say you are cool with this getting included in nevow -- I'd be happy to file the issue. # -*- python -*- from twisted.application import service, internet from nevow import compy, rend, inevow, appserver from formless import webform, annotate, iformless import multichoice ANIMALS = ['dogs', 'cats', 'snakes'] class IAnimals(annotate.TypedInterface): def remember(self, like=multichoice.MultipleChoice(choices=ANIMALS), hate=multichoice.MultipleChoice(choices=ANIMALS)): pass remember = annotate.autocallable(remember) class Animals(object): __implements__ = IAnimals like = None hate = None def remember(self, like, hate): self.like = like self.hate = hate print 'REMEMBER', self return self def __repr__(self): return '<%s like=%r hate=%r>' % ( self.__class__.__name__, self.like, self.hate, ) class MyResource(rend.Page): docFactory = rend.htmlstr( """\ <?xml version="1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:xi="http://nevow.com/ns/nevow/0.1"> <head> <title>Thingies</title> <link href="/form_css" rel="stylesheet" type="text/css" /> </head> <body> <nevow:invisible nevow:render="input"/> </body> </html> """) child_form_css = webform.defaultCSS def configurable_(self, context): try: return context.locate(inevow.IHand) except KeyError: return Animals() def render_input(self, context, data): formDefaults = context.locate(iformless.IFormDefaults) methodDefaults = formDefaults.getAllDefaults('remember') conf = self.locateConfigurable(context, '') methodDefaults['like'] = conf.original.like methodDefaults['hate'] = conf.original.hate print 'RENDER', conf.original return webform.renderForms() site = appserver.NevowSite(MyResource()) application = service.Application("multichoice-example") webServer = internet.TCPServer(8080, site) webServer.setServiceParent(application)
Yes, I am fine with this code going into Nevow. Sorry for the delay.. I just got back from vacation. On Mon, 05 Jul 2004 15:02:08 +0300, Tommi Virtanen <tv@tv.debian.net> wrote:
Justin Johnson wrote:
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.
Here's a cleaned up and modernized version, with an example.
Please explicitly say you are cool with this getting included in nevow -- I'd be happy to file the issue.
participants (4)
-
Donovan Preston -
Justin Johnson -
Tommi Virtanen -
vicky