/dojango/forms/fields.py
Python | 158 lines | 134 code | 19 blank | 5 comment | 3 complexity | 59b2e5881ea60389c4dd82c46cd67365 MD5 | raw file
- from django.forms import *
- from django.conf import settings as dj_settings
- from django.utils import formats
- from dojango.forms import widgets
- from dojango.util import json_encode
- __all__ = (
- 'Field', 'DEFAULT_DATE_INPUT_FORMATS', 'DEFAULT_TIME_INPUT_FORMATS', # original django classes
- 'DEFAULT_DATETIME_INPUT_FORMATS', 'MultiValueField', 'ComboField', # original django classes
- 'DojoFieldMixin', 'CharField', 'ChoiceField', 'TypedChoiceField',
- 'IntegerField', 'BooleanField', 'FileField', 'ImageField',
- 'DateField', 'TimeField', 'DateTimeField', 'SplitDateTimeField',
- 'RegexField', 'DecimalField', 'FloatField', 'FilePathField',
- 'MultipleChoiceField', 'NullBooleanField', 'EmailField',
- 'IPAddressField', 'URLField', 'SlugField',
- )
- class DojoFieldMixin(object):
- """
- A general mixin for all custom django/dojo form fields.
- It passes the field attributes in 'passed_attrs' to the form widget, so
- they can be used there. The widget itself then evaluates which of these
- fiels will be used.
- """
- passed_attrs = [ # forwarded field->widget attributes
- 'required',
- 'help_text',
- 'min_value',
- 'max_value',
- 'max_length',
- 'max_digits',
- 'decimal_places',
- 'js_regex', # special key for some dojo widgets
- ]
-
- def widget_attrs(self, widget):
- """Called, when the field is instanitating the widget. Here we collect
- all field attributes and pass it to the attributes of the widgets using
- the 'extra_field_attrs' key. These additional attributes will be
- evaluated by the widget and deleted within the 'DojoWidgetMixin'.
- """
- ret = {'extra_field_attrs': {}}
- for field_attr in self.passed_attrs:
- field_val = getattr(self, field_attr, None)
- #print field_attr, widget, field_val
- if field_val is not None:
- ret['extra_field_attrs'][field_attr] = field_val
- return ret
- ###############################################
- # IMPLEMENTATION OF ALL EXISTING DJANGO FIELDS
- ###############################################
- class CharField(DojoFieldMixin, fields.CharField):
- widget = widgets.ValidationTextInput
- class ChoiceField(DojoFieldMixin, fields.ChoiceField):
- widget = widgets.Select
-
- class TypedChoiceField(DojoFieldMixin, fields.TypedChoiceField):
- widget = widgets.Select
- class IntegerField(DojoFieldMixin, fields.IntegerField):
- widget = widgets.NumberTextInput
- decimal_places = 0
- class BooleanField(DojoFieldMixin, fields.BooleanField):
- widget = widgets.CheckboxInput
- class FileField(DojoFieldMixin, fields.FileField):
- widget = widgets.FileInput
-
- class ImageField(DojoFieldMixin, fields.ImageField):
- widget = widgets.FileInput
- class DateField(DojoFieldMixin, fields.DateField):
- widget = widgets.DateInput
-
- def __init__(self, input_formats=None, min_value=None, max_value=None, *args, **kwargs):
- kwargs['input_formats'] = input_formats or \
- tuple(list(formats.get_format('DATE_INPUT_FORMATS')) + [
- '%Y-%m-%dT%H:%M', '%Y-%m-%dT%H:%M:%S' # also support dojo's default date-strings
- ])
- self.max_value = max_value
- self.min_value = min_value
- super(DateField, self).__init__(*args, **kwargs)
- class TimeField(DojoFieldMixin, fields.TimeField):
- widget = widgets.TimeInput
-
- def __init__(self, input_formats=None, min_value=None, max_value=None, *args, **kwargs):
- kwargs['input_formats'] = input_formats or \
- tuple(list(formats.get_format('TIME_INPUT_FORMATS')) + [
- '%Y-%m-%dT%H:%M', '%Y-%m-%dT%H:%M:%S', 'T%H:%M:%S', 'T%H:%M' # also support dojo's default time-strings
- ])
- self.max_value = max_value
- self.min_value = min_value
- super(TimeField, self).__init__(*args, **kwargs)
- class SplitDateTimeField(DojoFieldMixin, fields.SplitDateTimeField):
- widget = widgets.DateTimeInput
-
- def __init__(self, min_value=None, max_value=None, *args, **kwargs):
- self.max_value = max_value
- self.min_value = min_value
- super(SplitDateTimeField, self).__init__(*args, **kwargs)
- # Overwrite the SplitDateTimeField
- # copied from original SplitDateTimeField of django
- errors = self.default_error_messages.copy()
- if 'error_messages' in kwargs:
- errors.update(kwargs['error_messages'])
- fields = (
- DateField(error_messages={'invalid': errors['invalid_date']}),
- TimeField(error_messages={'invalid': errors['invalid_time']}),
- )
- # copied from original MultiValueField of django
- for f in fields:
- f.required = False
- self.fields = fields
-
- DateTimeField = SplitDateTimeField # datetime-field is always splitted
-
- class RegexField(DojoFieldMixin, fields.RegexField):
- widget = widgets.ValidationTextInput
- js_regex = None # we additionally have to define a custom javascript regexp, because the python one is not compatible to javascript
-
- def __init__(self, js_regex=None, *args, **kwargs):
- self.js_regex = js_regex
- super(RegexField, self).__init__(*args, **kwargs)
-
- class DecimalField(DojoFieldMixin, fields.DecimalField):
- widget = widgets.NumberTextInput
- class FloatField(DojoFieldMixin, fields.FloatField):
- widget = widgets.ValidationTextInput
-
- class FilePathField(DojoFieldMixin, fields.FilePathField):
- widget = widgets.Select
-
- class MultipleChoiceField(DojoFieldMixin, fields.MultipleChoiceField):
- widget = widgets.SelectMultiple
-
- class NullBooleanField(DojoFieldMixin, fields.NullBooleanField):
- widget = widgets.NullBooleanSelect
-
- class EmailField(DojoFieldMixin, fields.EmailField):
- widget = widgets.EmailTextInput
-
- class IPAddressField(DojoFieldMixin, fields.IPAddressField):
- widget = widgets.IPAddressTextInput
-
- class URLField(DojoFieldMixin, fields.URLField):
- widget = widgets.URLTextInput
- class SlugField(DojoFieldMixin, fields.SlugField):
- widget = widgets.ValidationTextInput
- js_regex = '^[-\w]+$' # we cannot extract the original regex input from the python regex