Source code for ew.fields

from itertools import chain

from formencode import schema as fes
from formencode.foreach import ForEach
from formencode import validators as fev

from .validators import TimeConverter, DateConverter, UnicodeString
from .widget import Widget
from .utils import Bunch, safe_getitem
from . import core 

[docs]class FieldWidget(Widget, fev.Validator): '''Widget that also functions as a validator. Base class for all Form Field widgets.''' perform_validation=True validator=None @core.validator
[docs] def validate(self, value, state): return self.to_python(value, state)
@core.validator
[docs] def to_python(self, value, state): if self.perform_validation and self.validator: return self.validator.to_python(value, state) return value
[docs] def from_python(self, value, state): if self.perform_validation and self.validator: return self.validator.from_python(value, state) return value
[docs] def prepare_context(self, context): context = super(FieldWidget, self).prepare_context(context) try: context['value'] = self.from_python(context['value'], None) except: pass return context
[docs]class InputField(FieldWidget): defaults=dict( FieldWidget.defaults, name=None, label=None, value=None, errors=None, attrs=None, readonly=None, field_type=None, css_class=None, show_label=True, show_errors=True) validator = None perform_validation = True def __init__(self, **kw): self._if_missing = () super(InputField, self).__init__(**kw) if self.label is None and self.name: self.label = self.name.capitalize() def _get_if_missing(self): if self._if_missing == (): return self.validator.if_missing else: return self._if_missing def _set_if_missing(self, value): self._if_missing = value if_missing = property(_get_if_missing, _set_if_missing)
[docs]class HiddenField(InputField): defaults=dict( InputField.defaults, show_label=False, show_errors=False, field_type='hidden')
[docs]class CompoundField(InputField): defaults=dict( InputField.defaults, errors=None, hidden_fields=[], extra_fields=[], show_labels=True, error_class='fielderror') fields=[] chained_validators = [] @core.validator
[docs] def to_python(self, value, state=None): schema = self._make_schema() result = schema.to_python(value, state) return result
[docs] def from_python(self, value, state=None): if value is None: return None try: if not isinstance(value, dict): value = dict((k, getattr(value, k)) for k in dir(value)) result = self._make_schema().from_python(value, state) d = dict(value) d.update(result) return d except: return value
[docs] def resources(self): for f in chain(self.fields, self.hidden_fields, self.extra_fields): for r in f.resources(): yield r
[docs] def prepare_context(self, context): response = super(CompoundField, self).prepare_context(context) err = core.widget_context.validation_error if response.get('errors', None) is None and err: response['errors'] = err.unpack_errors() response['value'] = err.value if getattr(self, 'name', None): response['errors'] = response['errors'].get(self.name, None) response['value'] = response['value'].get(self.name, None) return response
[docs] def context_for(self, field): context = core.widget_context.render_context if not field.name: return Bunch( name=context.get('name', None), value=context.get('value', None), errors=context.get('errors', None)) if context.get('name'): name = context['name'] + '.' + field.name else: name = field.name r = Bunch( name=name, value=safe_getitem(context, 'value', field.name), errors=safe_getitem(context, 'errors', field.name)) return r
def _all_fields(self): return chain(self.fields, self.hidden_fields, self.extra_fields) def _make_schema(self): kwargs = dict((f.name, f) for f in self._all_fields() if f.name and getattr(f, 'perform_validation', False)) for f in self.fields: if f.name: continue if hasattr(f, '_make_schema'): kwargs.update(f._make_schema().fields) kwargs.update(chained_validators=self.chained_validators, ignore_key_missing=True, allow_extra_fields=True, filter_extra_fields=True) return fes.Schema(**kwargs)
[docs]class FieldSet(CompoundField): defaults=dict( CompoundField.defaults, show_label=False)
[docs]class RowField(CompoundField): pass
[docs]class RepeatedField(InputField): defaults=dict( InputField.defaults, errors=None, repetitions=3, error_class='fielderror') field=None chained_validators = [] def __init__(self, **kw): self._name = None super(RepeatedField, self).__init__(**kw) @core.validator
[docs] def to_python(self, value, state=None): return self._make_schema().to_python(value, state)
[docs] def from_python(self, value, state=None): if value is None: return None return self._make_schema().from_python(value, state)
[docs] def resources(self): return self.field.resources()
[docs] def prepare_context(self, context): response = super(RepeatedField, self).prepare_context(context) err = core.widget_context.validation_error if response.get('errors', None) is None and err: response['errors'] = err.unpack_errors() response['value'] = err.value if response.get('value', None) is not None: response['repetitions'] = len(response['value']) else: response['value'] = [ None ] * response['repetitions'] return response
[docs] def context_for(self, repetition): def get(coll, default=None): try: return coll[repetition] except (IndexError, KeyError): return default context = core.widget_context.render_context value = context.get('value') or [] name = context['name'] + '-' + unicode(repetition) r = Bunch( name=name, value=get(value, None), errors=None) if context.get('errors', None) is not None: r['errors'] = get(context['errors']) or {} return r
def _get_name(self): if self._name is None: if self.field: return self.field.name else: return self._name return self._name def _set_name(self, value): self._name = value name = property(_get_name, _set_name) def _make_schema(self): return ForEach(self.field, if_missing=[], if_empty=[])
[docs]class TableField(RepeatedField): show_label = False fields=[] hidden_fields=[] RowField=RowField def __init__(self, **kw): super(TableField, self).__init__(**kw) if self.field is None: fields = kw.get('fields', self.fields) hidden_fields = kw.get('hidden_fields', self.hidden_fields) name = self.name self.field = self.RowField(name=name, fields=fields, hidden_fields=hidden_fields) self.name = None
[docs]class TextField(InputField): validator = UnicodeString() defaults=dict( InputField.defaults, field_type='text')
[docs]class EmailField(TextField): validator = fev.Email()
[docs]class NumberField(TextField): validator = fev.Number()
[docs]class IntField(TextField): validator = fev.Int()
[docs]class DateField(TextField): validator=DateConverter() defaults=dict( TextField.defaults, attrs={'style':'width:6em'})
[docs]class TimeField(TextField): validator=TimeConverter(use_seconds=False) defaults=dict( TextField.defaults, attrs={'style':'width:5em'})
[docs]class TextArea(InputField): validator = UnicodeString() defaults=dict( InputField.defaults, cols=60)
[docs]class Checkbox(InputField): validator=fev.StringBool(if_empty=False, if_missing=False) defaults=dict( InputField.defaults, show_label=False, # don't show default label suppress_label=False, # if true, don't label the checkbox )
[docs] def from_python(self, value, state): if value: return 'CHECKED' else: return None
[docs]class SubmitButton(InputField): validator=UnicodeString(if_empty=None, if_missing=None) defaults=dict( InputField.defaults, show_label=False, css_class='submit')
[docs]class HTMLField(Widget): defaults=dict( Widget.defaults, show_label=False, text='') perform_validation=False
[docs]class LinkField(Widget): defaults=dict( Widget.defaults, href=None, attrs=None, label=None, text=None, show_label=False)