diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2018-05-24 12:45:09 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2018-06-12 08:49:06 +0200 |
commit | d8c465d783173e04caaf7db68e536b8aa777df00 (patch) | |
tree | 7f2ead38802ae262f6a22abecacd7ce42fa96600 /ishtar_common/widgets.py | |
parent | d807e2b7b96935174135bc76b6a22f3a0100bd95 (diff) | |
download | Ishtar-d8c465d783173e04caaf7db68e536b8aa777df00.tar.bz2 Ishtar-d8c465d783173e04caaf7db68e536b8aa777df00.zip |
Wizards - JSON fields: Manage dynamic list - list existing + dynamic add (refs #4089)
Diffstat (limited to 'ishtar_common/widgets.py')
-rw-r--r-- | ishtar_common/widgets.py | 87 |
1 files changed, 77 insertions, 10 deletions
diff --git a/ishtar_common/widgets.py b/ishtar_common/widgets.py index 442f12b9a..a20d33fc3 100644 --- a/ishtar_common/widgets.py +++ b/ishtar_common/widgets.py @@ -23,6 +23,7 @@ import logging from django import forms from django.conf import settings +from django.core.exceptions import ValidationError from django.core.files import File from django.core.urlresolvers import reverse, NoReverseMatch from django.db.models import fields @@ -101,18 +102,10 @@ class SelectReadonlyField(forms.ChoiceField): return bool(self.get_q().filter(pk=value).count()) -class Select2Multiple(forms.SelectMultiple): - def __init__(self, attrs=None, choices=(), remote=None, model=None, - new=None, available=None): - super(Select2Multiple, self).__init__(attrs, choices) - self.remote = remote - self.available = available - self.model = model - self.new = new - +class Select2Media(object): @property def media(self): - media = super(Select2Multiple, self).media + media = super(Select2Media, self).media css = { 'all': ('select2/css/select2.css',) } @@ -123,6 +116,80 @@ class Select2Multiple(forms.SelectMultiple): media.add_js(js) return media + +class Select2Dynamic(Select2Media, forms.Select): + """ + Select input using select, allowing dynamic creation. + """ + + def render(self, name, value, attrs=None, choices=()): + choices = choices or getattr(self, 'choices', []) + if value and value not in [key for key, v in choices]: + choices.insert(1, (value, value)) + self.choices = choices + klass = attrs and attrs.get('class') or '' + klass += ' ' if klass else '' + 'js-select2' + if not attrs: + attrs = {} + attrs['class'] = klass + if 'style' not in attrs: + if attrs.get('full-width', None): + attrs['style'] = "width: calc(100% - 60px)" + else: + attrs['style'] = "width: 370px" + options = [ + u"tags: true", + ] + ''' + msg = unicode( + _(u"Are you sure you want to add this term? (the addition is " + u"effective after registration of the element)") + ) + options.append(u"""createTag: function (params) {{ + return confirm("{}"); + }}""".format(msg)) + ''' + if attrs.get('full-width', None): + options.append(u"containerCssClass: 'full-width'") + + html = super(Select2Dynamic, self).render(name, value, attrs) + html += """<script type="text/javascript"> + $(document).ready(function() {{ + $("#id_{}").select2({{ {} }}); + }});</script> + """.format(name, u", ".join(options)) + return mark_safe(html) + + +class Select2DynamicField(forms.ChoiceField): + widget = Select2Dynamic + + def validate(self, value): + """ + Key can be added dynamically. Only check that the character " is not + used. + """ + if value and u'"' in value: + raise ValidationError( + _(u"The character \" is not accepted.") + ) + + def to_python(self, value): + """ + Strip value + """ + return super(Select2DynamicField, self).to_python(value).strip() + + +class Select2Multiple(Select2Media, forms.SelectMultiple): + def __init__(self, attrs=None, choices=(), remote=None, model=None, + new=None, available=None): + super(Select2Multiple, self).__init__(attrs, choices) + self.remote = remote + self.available = available + self.model = model + self.new = new + def get_q(self): q = self.model.objects if self.available: |