123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- from __future__ import unicode_literals
- from django.core.exceptions import ImproperlyConfigured
- from django import forms
- from django.forms.extras import SelectDateWidget
- from django.utils.translation import ugettext_lazy as _
- from mezzanine.conf import settings
- from mezzanine.core.forms import SplitSelectDateTimeWidget
- from mezzanine.utils.importing import import_dotted_path
- # Constants for all available field types.
- TEXT = 1
- TEXTAREA = 2
- EMAIL = 3
- CHECKBOX = 4
- CHECKBOX_MULTIPLE = 5
- SELECT = 6
- SELECT_MULTIPLE = 7
- RADIO_MULTIPLE = 8
- FILE = 9
- DATE = 10
- DATE_TIME = 11
- HIDDEN = 12
- NUMBER = 13
- URL = 14
- DOB = 15
- # Names for all available field types.
- NAMES = (
- (TEXT, _("Single line text")),
- (TEXTAREA, _("Multi line text")),
- (EMAIL, _("Email")),
- (NUMBER, _("Number")),
- (URL, _("URL")),
- (CHECKBOX, _("Check box")),
- (CHECKBOX_MULTIPLE, _("Check boxes")),
- (SELECT, _("Drop down")),
- (SELECT_MULTIPLE, _("Multi select")),
- (RADIO_MULTIPLE, _("Radio buttons")),
- (FILE, _("File upload")),
- (DATE, _("Date")),
- (DATE_TIME, _("Date/time")),
- (DOB, _("Date of birth")),
- (HIDDEN, _("Hidden")),
- )
- # Field classes for all available field types.
- CLASSES = {
- TEXT: forms.CharField,
- TEXTAREA: forms.CharField,
- EMAIL: forms.EmailField,
- CHECKBOX: forms.BooleanField,
- CHECKBOX_MULTIPLE: forms.MultipleChoiceField,
- SELECT: forms.ChoiceField,
- SELECT_MULTIPLE: forms.MultipleChoiceField,
- RADIO_MULTIPLE: forms.ChoiceField,
- FILE: forms.FileField,
- DATE: forms.DateField,
- DATE_TIME: forms.DateTimeField,
- DOB: forms.DateField,
- HIDDEN: forms.CharField,
- NUMBER: forms.FloatField,
- URL: forms.URLField,
- }
- # Widgets for field types where a specialised widget is required.
- WIDGETS = {
- TEXTAREA: forms.Textarea,
- CHECKBOX_MULTIPLE: forms.CheckboxSelectMultiple,
- RADIO_MULTIPLE: forms.RadioSelect,
- DATE: SelectDateWidget,
- DATE_TIME: SplitSelectDateTimeWidget,
- DOB: SelectDateWidget,
- HIDDEN: forms.HiddenInput,
- }
- # Some helper groupings of field types.
- CHOICES = (CHECKBOX, SELECT, RADIO_MULTIPLE)
- DATES = (DATE, DATE_TIME, DOB)
- MULTIPLE = (CHECKBOX_MULTIPLE, SELECT_MULTIPLE)
- # HTML5 Widgets
- html5_field = lambda name, base: type(str(""), (base,), {"input_type": name})
- if getattr(settings, "FORMS_USE_HTML5", False):
- WIDGETS.update({
- DATE: html5_field("date", forms.DateInput),
- DATE_TIME: html5_field("datetime", forms.DateTimeInput),
- DOB: html5_field("date", forms.DateInput),
- EMAIL: html5_field("email", forms.TextInput),
- NUMBER: html5_field("number", forms.TextInput),
- URL: html5_field("url", forms.TextInput),
- })
- # Allow extra fields types to be defined via the FORMS_EXTRA_FIELDS
- # setting, which should contain a sequence of three-item sequences,
- # each containing the ID, dotted import path for the field class,
- # and field name, for each custom field type.
- extra_fields = getattr(settings, "FORMS_EXTRA_FIELDS", [])
- for field_id, field_path, field_name in extra_fields:
- if field_id in CLASSES:
- err = "ID %s for field %s in FORMS_EXTRA_FIELDS already exists"
- raise ImproperlyConfigured(err % (field_id, field_name))
- CLASSES[field_id] = import_dotted_path(field_path)
- NAMES += ((field_id, _(field_name)),)
- # Similar to above but for widgets - expects a sequence of pairs,
- # each with a field ID as per above, and a dotted path to the custom
- # widget class to use for the corresponding form field.
- extra_widgets = getattr(settings, "FORMS_EXTRA_WIDGETS", [])
- for field_id, widget_path in extra_widgets:
- if field_id not in CLASSES:
- err = "ID %s in FORMS_EXTRA_WIDGETS does not match a field"
- raise ImproperlyConfigured(err % field_id)
- WIDGETS[field_id] = import_dotted_path(widget_path)
|