/dojango/forms/fields.py

https://github.com/thedrow/dojango · Python · 157 lines · 133 code · 19 blank · 5 comment · 3 complexity · c8cf79ac52cb4eec74717bd586d835ba MD5 · raw file

  1. from django.forms import *
  2. from django.conf import settings as dj_settings
  3. from django.utils import formats
  4. from dojango.forms import widgets
  5. from dojango.util import json_encode
  6. __all__ = (
  7. 'Field', 'MultiValueField', 'ComboField', # original django classes
  8. 'DojoFieldMixin', 'CharField', 'ChoiceField', 'TypedChoiceField',
  9. 'IntegerField', 'BooleanField', 'FileField', 'ImageField',
  10. 'DateField', 'TimeField', 'DateTimeField', 'SplitDateTimeField',
  11. 'RegexField', 'DecimalField', 'FloatField', 'FilePathField',
  12. 'MultipleChoiceField', 'NullBooleanField', 'EmailField',
  13. 'IPAddressField', 'URLField', 'SlugField',
  14. )
  15. class DojoFieldMixin(object):
  16. """
  17. A general mixin for all custom django/dojo form fields.
  18. It passes the field attributes in 'passed_attrs' to the form widget, so
  19. they can be used there. The widget itself then evaluates which of these
  20. fiels will be used.
  21. """
  22. passed_attrs = [ # forwarded field->widget attributes
  23. 'required',
  24. 'help_text',
  25. 'min_value',
  26. 'max_value',
  27. 'max_length',
  28. 'max_digits',
  29. 'decimal_places',
  30. 'js_regex', # special key for some dojo widgets
  31. ]
  32. def widget_attrs(self, widget):
  33. """Called, when the field is instanitating the widget. Here we collect
  34. all field attributes and pass it to the attributes of the widgets using
  35. the 'extra_field_attrs' key. These additional attributes will be
  36. evaluated by the widget and deleted within the 'DojoWidgetMixin'.
  37. """
  38. ret = {'extra_field_attrs': {}}
  39. for field_attr in self.passed_attrs:
  40. field_val = getattr(self, field_attr, None)
  41. #print field_attr, widget, field_val
  42. if field_val is not None:
  43. ret['extra_field_attrs'][field_attr] = field_val
  44. return ret
  45. ###############################################
  46. # IMPLEMENTATION OF ALL EXISTING DJANGO FIELDS
  47. ###############################################
  48. class CharField(DojoFieldMixin, fields.CharField):
  49. widget = widgets.ValidationTextInput
  50. class ChoiceField(DojoFieldMixin, fields.ChoiceField):
  51. widget = widgets.Select
  52. class TypedChoiceField(DojoFieldMixin, fields.TypedChoiceField):
  53. widget = widgets.Select
  54. class IntegerField(DojoFieldMixin, fields.IntegerField):
  55. widget = widgets.NumberTextInput
  56. decimal_places = 0
  57. class BooleanField(DojoFieldMixin, fields.BooleanField):
  58. widget = widgets.CheckboxInput
  59. class FileField(DojoFieldMixin, fields.FileField):
  60. widget = widgets.FileInput
  61. class ImageField(DojoFieldMixin, fields.ImageField):
  62. widget = widgets.FileInput
  63. class DateField(DojoFieldMixin, fields.DateField):
  64. widget = widgets.DateInput
  65. def __init__(self, input_formats=None, min_value=None, max_value=None, *args, **kwargs):
  66. kwargs['input_formats'] = input_formats or \
  67. tuple(list(formats.get_format('DATE_INPUT_FORMATS')) + [
  68. '%Y-%m-%dT%H:%M', '%Y-%m-%dT%H:%M:%S' # also support dojo's default date-strings
  69. ])
  70. self.max_value = max_value
  71. self.min_value = min_value
  72. super(DateField, self).__init__(*args, **kwargs)
  73. class TimeField(DojoFieldMixin, fields.TimeField):
  74. widget = widgets.TimeInput
  75. def __init__(self, input_formats=None, min_value=None, max_value=None, *args, **kwargs):
  76. kwargs['input_formats'] = input_formats or \
  77. tuple(list(formats.get_format('TIME_INPUT_FORMATS')) + [
  78. '%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
  79. ])
  80. self.max_value = max_value
  81. self.min_value = min_value
  82. super(TimeField, self).__init__(*args, **kwargs)
  83. class SplitDateTimeField(DojoFieldMixin, fields.SplitDateTimeField):
  84. widget = widgets.DateTimeInput
  85. def __init__(self, min_value=None, max_value=None, *args, **kwargs):
  86. self.max_value = max_value
  87. self.min_value = min_value
  88. super(SplitDateTimeField, self).__init__(*args, **kwargs)
  89. # Overwrite the SplitDateTimeField
  90. # copied from original SplitDateTimeField of django
  91. errors = self.default_error_messages.copy()
  92. if 'error_messages' in kwargs:
  93. errors.update(kwargs['error_messages'])
  94. fields = (
  95. DateField(error_messages={'invalid': errors['invalid_date']}),
  96. TimeField(error_messages={'invalid': errors['invalid_time']}),
  97. )
  98. # copied from original MultiValueField of django
  99. for f in fields:
  100. f.required = False
  101. self.fields = fields
  102. DateTimeField = SplitDateTimeField # datetime-field is always splitted
  103. class RegexField(DojoFieldMixin, fields.RegexField):
  104. widget = widgets.ValidationTextInput
  105. js_regex = None # we additionally have to define a custom javascript regexp, because the python one is not compatible to javascript
  106. def __init__(self, js_regex=None, *args, **kwargs):
  107. self.js_regex = js_regex
  108. super(RegexField, self).__init__(*args, **kwargs)
  109. class DecimalField(DojoFieldMixin, fields.DecimalField):
  110. widget = widgets.NumberTextInput
  111. class FloatField(DojoFieldMixin, fields.FloatField):
  112. widget = widgets.ValidationTextInput
  113. class FilePathField(DojoFieldMixin, fields.FilePathField):
  114. widget = widgets.Select
  115. class MultipleChoiceField(DojoFieldMixin, fields.MultipleChoiceField):
  116. widget = widgets.SelectMultiple
  117. class NullBooleanField(DojoFieldMixin, fields.NullBooleanField):
  118. widget = widgets.NullBooleanSelect
  119. class EmailField(DojoFieldMixin, fields.EmailField):
  120. widget = widgets.EmailTextInput
  121. class IPAddressField(DojoFieldMixin, fields.IPAddressField):
  122. widget = widgets.IPAddressTextInput
  123. class URLField(DojoFieldMixin, fields.URLField):
  124. widget = widgets.URLTextInput
  125. class SlugField(DojoFieldMixin, fields.SlugField):
  126. widget = widgets.ValidationTextInput
  127. js_regex = '^[-\w]+$' # we cannot extract the original regex input from the python regex