|
7 | 7 | from ietf.liaisons.models import LiaisonStatement |
8 | 8 |
|
9 | 9 | def select2_id_liaison_json(objs): |
10 | | - return json.dumps([{ "id": o.pk, "text": escape(o.title) } for o in objs]) |
| 10 | + return json.dumps([{ "id": o.pk, "text":u"[{}] {}".format(o.pk, escape(o.title)) } for o in objs]) |
11 | 11 |
|
12 | | -class SearchableLiaisonStatementField(forms.IntegerField): |
| 12 | +def select2_id_group_json(objs): |
| 13 | + return json.dumps([{ "id": o.pk, "text": escape(o.acronym) } for o in objs]) |
| 14 | + |
| 15 | +class SearchableLiaisonStatementsField(forms.CharField): |
13 | 16 | """Server-based multi-select field for choosing liaison statements using |
14 | 17 | select2.js.""" |
15 | 18 |
|
16 | | - def __init__(self, hint_text="Type in title to search for document", *args, **kwargs): |
17 | | - super(SearchableLiaisonStatementField, self).__init__(*args, **kwargs) |
| 19 | + def __init__(self, |
| 20 | + max_entries = None, |
| 21 | + hint_text="Type in title to search for document", |
| 22 | + model = LiaisonStatement, |
| 23 | + *args, **kwargs): |
| 24 | + kwargs["max_length"] = 10000 |
| 25 | + self.model = model |
| 26 | + self.max_entries = max_entries |
| 27 | + |
| 28 | + super(SearchableLiaisonStatementsField, self).__init__(*args, **kwargs) |
18 | 29 |
|
19 | | - self.widget.attrs["class"] = "select2-field" |
| 30 | + self.widget.attrs["class"] = "select2-field form-control" |
20 | 31 | self.widget.attrs["data-placeholder"] = hint_text |
21 | | - self.widget.attrs["data-max-entries"] = 1 |
| 32 | + if self.max_entries != None: |
| 33 | + self.widget.attrs["data-max-entries"] = self.max_entries |
| 34 | + |
| 35 | + def parse_select2_value(self, value): |
| 36 | + return [x.strip() for x in value.split(",") if x.strip()] |
22 | 37 |
|
23 | 38 | def prepare_value(self, value): |
24 | 39 | if not value: |
25 | | - value = None |
26 | | - elif isinstance(value, LiaisonStatement): |
27 | | - value = value |
28 | | - else: |
29 | | - value = LiaisonStatement.objects.exclude(approved=None).filter(pk=value).first() |
| 40 | + value = "" |
| 41 | + if isinstance(value, (int, long)): |
| 42 | + value = str(value) |
| 43 | + if isinstance(value, basestring): |
| 44 | + pks = self.parse_select2_value(value) |
| 45 | + value = self.model.objects.filter(pk__in=pks) |
| 46 | + if isinstance(value, LiaisonStatement): |
| 47 | + value = [value] |
30 | 48 |
|
31 | | - self.widget.attrs["data-pre"] = select2_id_liaison_json([value] if value else []) |
| 49 | + self.widget.attrs["data-pre"] = select2_id_liaison_json(value) |
32 | 50 |
|
33 | 51 | # doing this in the constructor is difficult because the URL |
34 | 52 | # patterns may not have been fully constructed there yet |
35 | | - self.widget.attrs["data-ajax-url"] = urlreverse("ajax_select2_search_liaison_statements") |
| 53 | + self.widget.attrs["data-ajax-url"] = urlreverse("ietf.liaisons.views.ajax_select2_search_liaison_statements") |
36 | 54 |
|
37 | | - return value |
| 55 | + return u",".join(unicode(o.pk) for o in value) |
38 | 56 |
|
39 | 57 | def clean(self, value): |
40 | | - value = super(SearchableLiaisonStatementField, self).clean(value) |
| 58 | + value = super(SearchableLiaisonStatementsField, self).clean(value) |
| 59 | + pks = self.parse_select2_value(value) |
41 | 60 |
|
42 | | - if value == None: |
43 | | - return None |
| 61 | + objs = self.model.objects.filter(pk__in=pks) |
44 | 62 |
|
45 | | - obj = LiaisonStatement.objects.filter(pk=value).first() |
46 | | - if not obj and self.required: |
47 | | - raise forms.ValidationError(u"You must select a value.") |
| 63 | + found_pks = [str(o.pk) for o in objs] |
| 64 | + failed_pks = [x for x in pks if x not in found_pks] |
| 65 | + if failed_pks: |
| 66 | + raise forms.ValidationError(u"Could not recognize the following groups: {pks}.".format(pks=", ".join(failed_pks))) |
48 | 67 |
|
49 | | - return obj |
| 68 | + if self.max_entries != None and len(objs) > self.max_entries: |
| 69 | + raise forms.ValidationError(u"You can select at most %s entries only." % self.max_entries) |
50 | 70 |
|
| 71 | + return objs |
0 commit comments