Quixote Extras
hist

<root> / shalabh / formutil.py

# $Id: formutil.py,v 1.2 2005/03/15 06:08:08 shalabh Exp $

# TitledForm - A form with a form title in a div (class=form-title) at
# the top of the form - useful for styling.

# UForm - A form that can co-exist with other UForms on the same page
# without getting confused about who was submitted. UForms are titled
# also.

# CheckedStringWidget - A string widget that ensures max size.

# CheckedTextWidget - A text widget that ensures max size.


from quixote import get_request, get_field
from quixote.html import htmltext
from quixote.form import Form, WidgetValueError, StringWidget, TextWidget


class TitledForm(Form):
    def __init__(self, *l, **kw):
        if 'title' in kw:
            self.title = kw['title']
            del kw['title']
        else:
            self.title = ''

        Form.__init__(self, *l, **kw)

    def _render_start(self):
        return Form._render_start(self) + (htmltext('<div class="form"><div class="form-title">%s</div>') % self.title)

    def _render_finish(self):
        return htmltext('</div>')  + Form._render_finish(self)


def get_parse_func(self):
    def parse(request=None):
        if not self._parsed:
            self._parsed = True
            if request is None:
                request = get_request()
            if self._form.is_submitted():
                try:
                    self._parse(request)
                except WidgetValueError, exc:
                    self.set_error(str(exc))
                if (self.required and self.value is None and
                    not self.has_error()):
                    self.set_error('required')
        return self.value
    return parse

class UForm(TitledForm):
    def __init__(self, name, *l, **kw):
        self.name = name
        kw['name'] = name
        TitledForm.__init__(self, *l, **kw)
        self.add_hidden("_uform_name", value=name)

    def is_submitted(self):
        return TitledForm.is_submitted(self) and get_field('_uform_name')==self.name

    def add(self, widget_class, name, *args, **kwargs):
        TitledForm.add(self, widget_class, name, *args, **kwargs)
        w = self.get_widget(name)
        w._form = self
        w.parse = get_parse_func(w)


class CheckedStringWidget(StringWidget):

    def __init__(self, *l, **kw):
        if 'length' in kw:
            self.length = kw['length']
            if 'maxlength' not in [k.lower() for k in kw]:
                kw['maxlength'] = str(self.length)
            del kw['length']

        StringWidget.__init__(self, *l, **kw)

    def _parse(self, request):
        StringWidget._parse(self, request)
        if self.value is not None:
            if len(self.value.decode('utf-8'))>self.length:
                self.error = "too long, only %s characters allowed" % self.length


class CheckedTextWidget(TextWidget):

    def __init__(self, *l, **kw):
        if 'length' in kw:
            self.length = kw['length']

            # unfortunately, textarea does not have a 'maxlength', so
            # the browser cannot be told to limit user input (short of
            # writing some javascript)

            del kw['length']

        TextWidget.__init__(self, *l, **kw)

    def _parse(self, request):
        TextWidget._parse(self, request)
        if self.value is not None:
            if len(self.value.decode('utf-8'))>self.length:
                self.error = "too long, only %s characters allowed" % self.length