# -*- test-case-name: twisted.test.test_woven -*- # # WORK IN PROGRESS: HARD HAT REQUIRED # from __future__ import nested_scopes # Twisted Imports from twisted.python import formmethod, failure from twisted.python.components import registerAdapter, getAdapter from twisted.web import domhelpers, resource from twisted.internet import defer # Sibling Imports from twisted.web.woven import model, view, controller, widgets, input, interfaces, tapestry from twisted.web.microdom import parseString, lmx def getValue(request, argument): """Return value for form inpurt.""" values = request.args.get(argument.name, None) if values: try: return argument.coerce(values[0]) except formmethod.InputError: return values[0] return argument.default def getValues(request, argument): """Return values for form inpurt.""" values = request.args.get(argument.name, None) if values: try: return argument.coerce(values) except formmethod.InputError: return values return argument.default class FormFillerWidget(widgets.Widget): def createShell(self, request, node, data): """Create a `shell' node that will hold the additional form elements, if one is required. """ return lmx(node).table(border="0") def input_single(self, request, content, arg): return content.input(type="text", size="60", name=arg.name, value=str(getValue(request, arg))) def input_text(self, request, content, arg): r = content.textarea(cols="60", rows="10", name=arg.name, wrap="virtual") r.text(str(getValue(request, arg))) return r input_integer = input_single input_string = input_single input_float = input_single def input_choice(self, request, content, arg): s = content.select(name=arg.name) default = getValue(request, arg) for tag, value, desc in arg.choices: if tag == default: kw = {'selected' : '1'} else: kw = {} s.option(value=tag, **kw).text(desc) return s def input_radiogroup(self, request, content, arg): s = content.div() defaults = getValues(request, arg) for tag, value, desc in arg.choices: if tag in defaults: kw = {'checked' : '1'} else: kw = {} s.div().input(name=arg.name, type="radio", **kw).text(desc) return s def input_checkgroup(self, request, content, arg): s = content.div() defaults = getValues(request, arg) for tag, value, desc in arg.choices: if tag in defaults: kw = {'checked' : '1'} else: kw = {} s.input(type="checkbox", name=arg.name, value=tag, **kw).text(desc) return s def input_boolean(self, request, content, arg): if getValue(request, arg): kw = {'checked' : '1'} else: kw = {} i = content.input(type="checkbox", name=arg.name, **kw) return i def input_password(self, request, content, arg): return content.input(type="password", size="60", name=arg.name) def input_flags(self, request, content, arg): defaults = getValues(request, arg) for key, val, label in arg.flags: if key in defaults: kw = {'checked' : '1'} else: kw = {} nn = content.input(type="checkbox", name=arg.name, value=str(key), **kw) nn.text(label) return content def input_hidden(self, request, content, arg): return content.input(type="hidden", name=arg.name, value=getValue(request, arg)) def createInput(self, request, shell, arg): name = arg.__class__.__name__.lower() imeth = getattr(self,"input_"+name) if name == "hidden": return (imeth(request, shell, arg).node, lmx()) else: tr = shell.tr() tr.td(align="right", valign="top").text(arg.getShortDescription()+":") content = tr.td(valign="top") return (imeth(request, content, arg).node, content.div(style="color: green"). text(arg.getLongDescription()).node) def setUp(self, request, node, data): # node = widgets.Widget.generateDOM(self,request,node) lmn = lmx(node) if not node.hasAttribute('action'): lmn['action'] = (request.prepath+request.postpath)[-1] if not node.hasAttribute("method"): lmn['method'] = 'post' lmn['enctype'] = 'multipart/form-data' self.errorNodes = errorNodes = {} # name: nodes which trap errors self.inputNodes = inputNodes = {} for errorNode in domhelpers.findElementsWithAttribute(node, 'errorFor'): errorNodes[errorNode.getAttribute('errorFor')] = errorNode argz={} # list to figure out which nodes are in the template already and which aren't for arg in self.model.fmethod.getArgs(): argz[arg.name] = arg for inNode in domhelpers.getElementsByTagName(node, 'input'): nName = inNode.getAttribute("name") assert argz.has_key(nName), "method signature %s does not define argument %s" % (self.model.original, nName) inputNodes[nName] = inNode del argz[nName] if argz: shell = self.createShell(request, node, data) for remArg in argz.values(): inputNode, errorNode = self.createInput(request, shell, remArg) errorNodes[remArg.name] = errorNode inputNodes[remArg.name] = inputNode # TODO: 'submit' hint to make a list of multiple buttons # clear button lmn.input(type="submit") class FormErrorWidget(FormFillerWidget): def setUp(self, request, node, data): FormFillerWidget.setUp(self, request, node, data) for k, f in self.model.err.items(): en = self.errorNodes[k] tn = self.inputNodes[k] for n in en, tn: n.setAttribute('style', "color: red") en.childNodes[:]=[] # gurfle, CLEAR IT NOW!@# if isinstance(f, failure.Failure): f = f.getErrorMessage() lmx(en).text(str(f)) class FormDisplayModel(model.MethodModel): def initialize(self, fmethod): self.fmethod = fmethod class FormErrorModel(FormDisplayModel): def initialize(self, fmethod, args, err): FormDisplayModel.initialize(self, fmethod) self.args = args if isinstance(err, Exception): self.err = getattr(err, "descriptions", {}) self.desc = err else: self.err = err self.desc = "Please try again" def wmfactory_description(self): return str(self.desc) class ThankYou(view.View): template = '''