datatracker/ietf/person/fields.py
Ole Laursen a1a13323d2 Use hint text instead of Django help text for providing the help for
EmailsField and clarify the text displayed when the input is invalid
so it's hopefully more clear what happens
 - Legacy-Id: 8272
2014-08-17 09:02:21 +00:00

66 lines
2.7 KiB
Python

import json
from django.utils.html import escape
from django.utils.functional import lazy
from django import forms
from django.core.urlresolvers import reverse as urlreverse
import debug # pyflakes:ignore
from ietf.person.models import Email
def json_emails(emails):
if isinstance(emails, basestring):
emails = Email.objects.filter(address__in=[x.strip() for x in emails.split(",") if x.strip()]).select_related("person")
return json.dumps([{"id": e.address + "", "name": escape(u"%s <%s>" % (e.person.name, e.address))} for e in emails])
class EmailsField(forms.CharField):
"""Multi-select field using jquery.tokeninput.js. Since the API of
tokeninput" is asymmetric, we have to pass it a JSON
representation on the way out and parse the ids coming back as a
comma-separated list on the way in."""
def __init__(self, *args, **kwargs):
kwargs["max_length"] = 1000
self.max_entries = kwargs.pop("max_entries", None)
hint_text = kwargs.pop("hint_text", "Type in name or email to search for person and email address")
super(EmailsField, self).__init__(*args, **kwargs)
self.widget.attrs["class"] = "tokenized-field"
self.widget.attrs["data-ajax-url"] = lazy(urlreverse, str)("ajax_search_emails") # make this lazy to prevent initialization problem
self.widget.attrs["data-hint-text"] = hint_text
if self.max_entries != None:
self.widget.attrs["data-max-entries"] = self.max_entries
def parse_tokenized_value(self, value):
return [x.strip() for x in value.split(",") if x.strip()]
def prepare_value(self, value):
if not value:
value = ""
if isinstance(value, basestring):
addresses = self.parse_tokenized_value(value)
value = Email.objects.filter(address__in=addresses).select_related("person")
self.widget.attrs["data-pre"] = json_emails(value)
return ",".join(e.address for e in value)
def clean(self, value):
value = super(EmailsField, self).clean(value)
addresses = self.parse_tokenized_value(value)
emails = Email.objects.filter(address__in=addresses).select_related("person")
found_addresses = [e.address for e in emails]
failed_addresses = [x for x in addresses if x not in found_addresses]
if failed_addresses:
raise forms.ValidationError(u"Could not recognize the following email addresses: %s. You can only input addresses already registered in the Datatracker." % ", ".join(failed_addresses))
if self.max_entries != None and len(emails) > self.max_entries:
raise forms.ValidationError(u"You can only select at most %s entries." % self.max_entries)
return emails