diff options
| author | Valérie-Emma Leroux <valerie-emma.leroux@iggdrasil.net> | 2017-04-07 11:40:31 +0200 | 
|---|---|---|
| committer | Valérie-Emma Leroux <valerie-emma.leroux@iggdrasil.net> | 2017-04-07 11:40:31 +0200 | 
| commit | 655236dd5d04d6527184a58ef8622e75c73f8a65 (patch) | |
| tree | f773b80964981c231c892ee5255b94285bc5620a /ishtar_common/widgets.py | |
| parent | dc08e5f643562a6ecf3b208c1e2cd44e5350af3c (diff) | |
| parent | a4f1766d2217b1a3bc4d1d17625d9d808eed7416 (diff) | |
| download | Ishtar-655236dd5d04d6527184a58ef8622e75c73f8a65.tar.bz2 Ishtar-655236dd5d04d6527184a58ef8622e75c73f8a65.zip | |
Merge branch 'master' of git.iggdrasil.net:/srv/git/ishtar
Conflicts:
	archaeological_operations/templates/ishtar/sheet_operation.html
Diffstat (limited to 'ishtar_common/widgets.py')
| -rw-r--r-- | ishtar_common/widgets.py | 138 | 
1 files changed, 96 insertions, 42 deletions
| diff --git a/ishtar_common/widgets.py b/ishtar_common/widgets.py index 3fbf24f29..94709406c 100644 --- a/ishtar_common/widgets.py +++ b/ishtar_common/widgets.py @@ -1,6 +1,6 @@  #!/usr/bin/env python  # -*- coding: utf-8 -*- -# Copyright (C) 2010-2016 Étienne Loks  <etienne.loks_AT_peacefrogsDOTnet> +# Copyright (C) 2010-2017 Étienne Loks  <etienne.loks_AT_peacefrogsDOTnet>  # Copyright (C) 2007  skam <massimo dot scamarcia at gmail.com>  #                          (http://djangosnippets.org/snippets/233/) @@ -45,21 +45,89 @@ reverse_lazy = lazy(reverse, unicode)  class Select2Multiple(forms.SelectMultiple): -    class Media: +    def __init__(self, attrs=None, choices=(), remote=None, model=None, +                 available=None): +        super(Select2Multiple, self).__init__(attrs, choices) +        self.remote = remote +        self.available = available +        self.model = model + +    @property +    def media(self): +        media = super(Select2Multiple, self).media          css = {              'all': ('select2/css/select2.css',)          } -        js = ('select2/js/select2.min.js', -              'select2/js/init.js') +        js = ['select2/js/select2.min.js'] +        for lang_code, lang in settings.LANGUAGES: +            js.append('select2/js/i18n/{}.js'.format(lang_code)) +        media.add_css(css) +        media.add_js(js) +        return media + +    def get_q(self): +        q = self.model.objects +        if self.available: +            q = q.filter(available=True) +        return q + +    def get_choices(self): +        for i in self.get_q().all(): +            yield (i.pk, unicode(i))      def render(self, name, value, attrs=None, choices=()): +        self.remote = unicode(self.remote) +        if self.remote in ('None', 'false'): +            # test on lazy object is buggy... so we have this ugly test +            self.remote = None +        if not choices and not self.remote and self.model: +            choices = self.get_choices()          klass = attrs and attrs.get('class') or ''          klass += ' ' if klass else '' + 'js-select2'          if not attrs:              attrs = {}          attrs['class'] = klass -        return super(Select2Multiple, self).render(name, value, attrs, +        attrs['style'] = "width: 370px" +        options = "" +        if self.remote: +            options = """{ +            ajax: { +                url: '%s', +                delay: 250, +                dataType: 'json', +                minimumInputLength: 2, +                processResults: function (data) { +                 if(!data) return {results: []}; +                 var result = $.map(data, function (item) { +                        return { +                            text: item['value'], +                            id: item['id'] +                        } +                      }); +                 return { +                    results: result +                  } +                } +              } +            }""" % self.remote +            if value: +                choices = [] +                if type(value) not in (list, tuple): +                    value = value.split(',') +                for v in value: +                    try: +                        choices.append((v, self.model.objects.get(pk=v))) +                    except (self.model.DoesNotExist, ValueError): +                        # an old reference ? it should not happen +                        pass +        html = super(Select2Multiple, self).render(name, value, attrs,                                                     choices) +        html += """<script type="text/javascript"> +        $(document).ready(function() {{ +            $("#id_{}").select2({}); +        }});</script> +        """.format(name, options) +        return mark_safe(html)  class CheckboxSelectMultiple(CheckboxSelectMultipleBase): @@ -77,49 +145,35 @@ class CheckboxSelectMultiple(CheckboxSelectMultipleBase):                                                            choices) -class MultipleAutocompleteField(forms.MultipleChoiceField): +class Select2MultipleField(forms.MultipleChoiceField):      def __init__(self, *args, **kwargs): -        self.model = None +        remote = None +        if 'remote' in kwargs: +            remote = kwargs.pop('remote') +        self.model, self.remote = None, None          if 'model' in kwargs:              self.model = kwargs.pop('model') -        if 'choices' not in kwargs and self.model: -            kwargs['choices'] = [] -        new = kwargs.pop('new') if 'new' in kwargs else None -        if 'widget' not in kwargs and self.model: -            kwargs['widget'] = JQueryAutoComplete( -                reverse_lazy('autocomplete-' + self.model.__name__.lower()), -                associated_model=self.model, new=new, -                multiple=True) -        super(MultipleAutocompleteField, self).__init__(*args, **kwargs) - -    def get_choices(self): -        return [(i.pk, unicode(i)) for i in self.model.objects.all()] +            if remote: +                self.remote = reverse_lazy( +                    'autocomplete-' + self.model.__name__.lower()) +        self.available = False +        if 'available' in kwargs: +            self.available = kwargs.pop('available') +        kwargs['widget'] = Select2Multiple(model=self.model, +                                           available=self.available, +                                           remote=self.remote) +        super(Select2MultipleField, self).__init__(*args, **kwargs) + +    def get_q(self): +        q = self.model.objects +        if self.available: +            q = q.filter(available=True) +        return q      def valid_value(self, value):          if not self.model: -            return super(MultipleAutocompleteField, self).valid_value(value) -        return bool(self.model.objects.filter(pk=value).count()) - -    def clean(self, value): -        if value: -            # clean JS messup with values -            try: -                if type(value) not in (list, tuple): -                    value = [int(value)] -                else: -                    val = value -                    value = [] -                    for v in val: -                        v = unicode(v).strip('[').strip(']')\ -                                      .strip('u').strip("'").strip('"') -                        value += [int(va.strip()) -                                  for va in list(set(v.split(','))) -                                  if va.strip()] -            except (TypeError, ValueError): -                value = [] -        else: -            value = [] -        return super(MultipleAutocompleteField, self).clean(value) +            return super(Select2MultipleField, self).valid_value(value) +        return bool(self.get_q().filter(pk=value).count())  class DeleteWidget(forms.CheckboxInput): | 
