old version
------------
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 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 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)
compy.registerAdapter(MultipleChoiceRenderer, MultipleChoice, iformless.ITypedRenderer)
compy.registerAdapter(MultipleChoiceInputProcessor, MultipleChoice, iformless.IInputProcessor)
new version
------------
same as above except for below I inherit from object instead of compy.Adapter,
and registerAdapter is imported from twisted.python.components.
class MultipleChoiceInputProcessor(object):
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)
registerAdapter(MultipleChoiceRenderer, MultipleChoice, iformless.ITypedRenderer)
registerAdapter(MultipleChoiceInputProcessor, MultipleChoice, iformless.IInputProcessor)
I'm getting the following long ugly error though.
exceptions.TypeError: default __new__ takes no parameters
D:\Python24\lib\site-packages\twisted\internet\defer.py, line 107 in maybeDeferred
105
106 try:
107 result = f(*args, **kw)
108 except:
Locals
args (PageContext(tag=<ratcontrol.web.pages.LoggedIn object at 0x0126C570>, remembrances={'formless.iformless.IConfigurableFactory': <ratcontrol.web.pages.LoggedIn object at 0x0126C570>, 'nevow.inevow.ICurrentSegments': (), 'formless.iformless.IBinding': <MethodBinding applytriggers=Method at 0x119c6f0>, 'nevow.inevow.IRemainingSegments': ('freeform_post!applytriggers!applytriggers',), 'nevow.inevow.IRequest': <GET /freeform_post!applytriggers!applytriggers?vobs=&site=bangalore&applytriggers=applytriggers HTTP/1.1>, 'nevow.inevow.IResource': <ratcontrol.web.pages.LoggedIn object at 0x0126C570>, 'formless.iformless.IConfigurable': TypedInterfaceConfigurable(<ratcontrol.web.forms.ApplytriggersForm object at 0x0125DD70>)}), 'applytriggers', {'vobs': [''], 'site': ['bangalore'], 'applytriggers': ['applytriggers']})
kw {}
f <bound method TypedInterfaceConfigurable.postForm of TypedInterfaceConfigurable(<ratcontrol.web.forms.ApplytriggersForm object at 0x0125DD70>)>
D:\Python24\Lib\site-packages\formless\configurable.py, line 116 in postForm
114
115 bindingProcessor = iformless.IInputProcessor(binding)
116 rv = bindingProcessor.process(ctx, binding.boundTo, args)
117 ctx.remember(rv, inevow.IHand)
Locals
bindingProcessor <formless.processors.ProcessMethodBinding instance at 0x012A23F0>
args {'vobs': [''], 'site': ['bangalore'], 'applytriggers': ['applytriggers']}
binding <MethodBinding applytriggers=Method at 0x119c6f0>
ctx PageContext(tag=<ratcontrol.web.pages.LoggedIn object at 0x0126C570>, remembrances={'formless.iformless.IConfigurableFactory': <ratcontrol.web.pages.LoggedIn object at 0x0126C570>, 'nevow.inevow.ICurrentSegments': (), 'formless.iformless.IBinding': <MethodBinding applytriggers=Method at 0x119c6f0>, 'nevow.inevow.IRemainingSegments': ('freeform_post!applytriggers!applytriggers',), 'nevow.inevow.IRequest': <GET /freeform_post!applytriggers!applytriggers?vobs=&site=bangalore&applytriggers=applytriggers HTTP/1.1>, 'nevow.inevow.IResource': <ratcontrol.web.pages.LoggedIn object at 0x0126C570>, 'formless.iformless.IConfigurable': TypedInterfaceConfigurable(<ratcontrol.web.forms.ApplytriggersForm object at 0x0125DD70>)})
iformless <module 'formless.iformless' from 'D:\Python24\lib\site-packages\formless\iformless.pyc'>
Globals
inevow <module 'nevow.inevow' from 'D:\Python24\lib\site-packages\nevow\inevow.pyc'>
D:\Python24\Lib\site-packages\formless\processors.py, line 103 in process
101 context = WovenContext(context, faketag)
102 context.remember(binding, iformless.IBinding)
103 results[name] = iformless.IInputProcessor(binding.typedValue).process(context, boundTo, data.get(name, ['']))
104 except formless.InputError, e:
Locals
e <formless.annotate.InputError instance at 0x012A22D8>
name 'trigger_names'
binding <Argument trigger_names=AllTriggers at 0x119c5f0>
boundTo <ratcontrol.web.forms.ApplytriggersForm object at 0x0125DD70>
results {'vobs': '', 'request': <GET /freeform_post!applytriggers!applytriggers?vobs=&site=bangalore&applytriggers=applytriggers HTTP/1.1>, 'site': 'bangalore'}
context WovenContext(tag=Tag('html'), remembrances={'formless.iformless.IBinding': <Argument trigger_names=AllTriggers at 0x119c5f0>})
data {'vobs': [''], 'site': ['bangalore'], 'applytriggers': ['applytriggers']}
typedValue <formless.annotate.Method object at 0x0119C6D0>
Globals
process <function process at 0x00F075F0>
faketag Tag('html')
formless <module 'formless' from 'D:\Python24\lib\site-packages\formless\__init__.pyc'>
WovenContext <class 'nevow.context.WovenContext'>
iformless <module 'formless.iformless' from 'D:\Python24\lib\site-packages\formless\iformless.pyc'>
D:\Python24\Lib\site-packages\zope\interface\interface.py, line 676 in __call__
674 return adapter
675
676 adapter = self.__adapt__(obj)
677
Locals
self <InterfaceClass formless.iformless.IInputProcessor>
obj <ratcontrol.web.typed.AllTriggers object at 0x0119C510>
D:\Python24\Lib\site-packages\zope\interface\interface.py, line 744 in __adapt__
742
743 for hook in adapter_hooks:
744 adapter = hook(self, obj)
745 if adapter is not None:
Locals
hook <function _hook at 0x00B3E170>
self <InterfaceClass formless.iformless.IInputProcessor>
obj <ratcontrol.web.typed.AllTriggers object at 0x0119C510>
Globals
adapter_hooks [<function _hook at 0x00B3E170>]
D:\Python24\lib\site-packages\twisted\python\components.py, line 96 in _hook
94 return None
95 else:
96 return factory(ob)
97interface.adapter_hooks.append(_hook)
Locals
factory <class 'ratcontrol.web.typed.MultipleChoiceInputProcessor'>
ob <ratcontrol.web.typed.AllTriggers object at 0x0119C510>
Globals
interface <module 'zope.interface.interface' from 'D:\Python24\lib\site-packages\zope\interface\interface.pyc'>
_hook <function _hook at 0x00B3E170>
exceptions.TypeError: default __new__ takes no parameters