""" HTML forms (part of web.py) """ import copy, re import webapi as web import utils, net def attrget(obj, attr, value=None): if hasattr(obj, 'has_key') and obj.has_key(attr): return obj[attr] if hasattr(obj, attr): return getattr(obj, attr) return value class Form: def __init__(self, *inputs, **kw): self.inputs = inputs self.valid = True self.note = None self.validators = kw.pop('validators', []) def __call__(self, x=None): o = copy.deepcopy(self) if x: o.validates(x) return o def render(self): out = '' out += self.rendernote(self.note) out += '\n' for i in self.inputs: out += ' ' % (i.id, i.description) out += "" out += '\n' % (i.id, self.rendernote(i.note)) out += "
"+i.pre+i.render()+i.post+"%s
" return out def rendernote(self, note): if note: return '%s' % note else: return "" def validates(self, source=None, _validate=True, **kw): source = source or kw or web.input() out = True for i in self.inputs: v = attrget(source, i.name) if _validate: out = i.validate(v) and out else: i.value = v if _validate: out = out and self._validate(source) self.valid = out return out def _validate(self, value): self.value = value for v in self.validators: if not v.valid(value): self.note = v.msg return False return True def fill(self, source=None, **kw): return self.validates(source, _validate=False, **kw) def __getitem__(self, i): for x in self.inputs: if x.name == i: return x raise KeyError, i def _get_d(self): #@@ should really be form.attr, no? return utils.storage([(i.name, i.value) for i in self.inputs]) d = property(_get_d) class Input(object): def __init__(self, name, *validators, **attrs): self.description = attrs.pop('description', name) self.value = attrs.pop('value', None) self.pre = attrs.pop('pre', "") self.post = attrs.pop('post', "") self.id = attrs.setdefault('id', name) if 'class_' in attrs: attrs['class'] = attrs['class_'] del attrs['class_'] self.name, self.validators, self.attrs, self.note = name, validators, attrs, None def validate(self, value): self.value = value for v in self.validators: if not v.valid(value): self.note = v.msg return False return True def render(self): raise NotImplementedError def addatts(self): str = "" for (n, v) in self.attrs.items(): str += ' %s="%s"' % (n, net.websafe(v)) return str #@@ quoting class Textbox(Input): def render(self): x = '' class Checkbox(Input): def render(self): x = '