[#2534] Fait du champ "ref" dans EtablissementBase un champ one-to-one
authorEric Mc Sween <eric.mcsween@auf.org>
Wed, 1 Feb 2012 16:37:57 +0000 (11:37 -0500)
committerEric Mc Sween <eric.mcsween@auf.org>
Wed, 1 Feb 2012 16:37:57 +0000 (11:37 -0500)
Modifié l'autocomplete pour qu'il ne propose pas des établissements existants

auf/django/references/forms.py
auf/django/references/models.py
auf/django/references/static/references/etablissement-form.js [deleted file]
auf/django/references/static/references/jquery.etablissement-autocomplete.js [new file with mode: 0644]
auf/django/references/views.py

index eb82bd8..2455aaf 100644 (file)
@@ -1,12 +1,39 @@
+# encoding: utf-8
+
 from django import forms
 from django import forms
+from django.utils.safestring import mark_safe
 
 from auf.django.references import models as ref
 
 
 from auf.django.references import models as ref
 
+
+class EtablissementAutocompleteWidget(forms.TextInput):
+    """
+    Champ texte qui émet les invocations javascript pour gérer
+    l'autocomplétion des établissements.
+    """
+
+    def __init__(self):
+        super(EtablissementAutocompleteWidget, self).__init__(attrs={
+            'autocomplete': 'off'
+        });
+        self.exclude_refs = None
+
+    def render(self, name, value, attrs=None):
+        widget = super(EtablissementAutocompleteWidget, self).render(name, value, attrs=attrs)
+        id = attrs and attrs.get('id')
+        if id:
+            args = ("'%s'" % self.exclude_refs) if self.exclude_refs else ''
+            js = """
+                 <script type="text/javascript">
+                 $(function() { $('#%s').etablissement_autocomplete(%s); })
+                 </script>
+                 """ % (id, args)
+            widget += js
+        return mark_safe(widget)
+
+
 class EtablissementForm(forms.ModelForm):
 class EtablissementForm(forms.ModelForm):
-    nom = forms.CharField(widget=forms.TextInput(attrs={
-        'class': 'etablissement-autocomplete',
-        'autocomplete': 'off'
-    }))
+    nom = forms.CharField(widget=EtablissementAutocompleteWidget)
 
     class Meta:
         model = ref.EtablissementBase
 
     class Meta:
         model = ref.EtablissementBase
@@ -18,6 +45,11 @@ class EtablissementForm(forms.ModelForm):
         js = (
             'references/jquery.min.js',
             'references/jquery-ui.min.js',
         js = (
             'references/jquery.min.js',
             'references/jquery-ui.min.js',
-            'references/etablissement-form.js',
+            'references/jquery.etablissement-autocomplete.js',
         )
 
         )
 
+    def __init__(self, *args, **kwargs):
+        super(EtablissementForm, self).__init__(*args, **kwargs)
+        model = self._meta.model
+        ref_name = model._meta.get_field('ref').rel.related_name
+        self.fields['nom'].widget.exclude_refs = ref_name
index d42e48c..816920d 100644 (file)
@@ -423,7 +423,8 @@ class Etablissement(managedref.Etablissement):
 ### Modèles abstraits
 
 class EtablissementBase(managedref.EtablissementBase):
 ### Modèles abstraits
 
 class EtablissementBase(managedref.EtablissementBase):
-    ref = models.ForeignKey(Etablissement, blank=True, null=True)
+    ref = models.OneToOneField(Etablissement, blank=True, null=True,
+                               related_name='%(app_label)s_%(class)s')
 
     class Meta:
         abstract = True
 
     class Meta:
         abstract = True
diff --git a/auf/django/references/static/references/etablissement-form.js b/auf/django/references/static/references/etablissement-form.js
deleted file mode 100644 (file)
index 35138e5..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-$(function() {
-
-    function set_ref_etablissement(form, id) {
-        form.find('[name=ref]').val(id);
-        $.get('/references/etablissements/' + id + '.json', function(data) {
-            for (field in data) {
-                if (field != 'id') {
-                    var widget = form.find('[name=' + field + ']');
-                    var value = $('<span class="etablissement-value"></span>');
-                    value.insertBefore(widget);
-                    if (widget.is(':checkbox')) {
-                        value.append('<img src="/static/references/icon-' +
-                                     (data[field] ? 'yes' : 'no') + '.gif" alt="' +
-                                     (data[field] ? 'oui' : 'non') + '/>');
-                        widget.attr('checked', data[field]);
-                    }
-                    else {
-                        value.insertBefore(widget);
-                        if (widget.is('select')) {
-                            value.append(widget.find('option[value=' + data[field] + ']').text());
-                        }
-                        else {
-                            value.append(data[field]);
-                        }
-                        widget.val(data[field]);
-                    }
-
-                    if (field == 'nom') {
-                        var button = $(
-                            '<button type="button" class="etablissement-change-button">Modifier</button>'
-                        );
-                        value.append(' ');
-                        button.appendTo(value);
-                        button.click(function() { unset_ref_etablissement(form); })
-                    }
-                    widget.addClass('etablissement-hidden').hide();
-                    widget.next('.add-another,.datetimeshortcuts').addClass('etablissement-hidden').hide();
-                }
-            }
-        });
-    }
-
-    function unset_ref_etablissement(form) {
-        form.find('[name=ref]').val('');
-        form.find('[name=nom]').val('');
-        form.find('.etablissement-value').remove();
-        form.find('.etablissement-hidden').show();
-    }
-
-    $('input.etablissement-autocomplete').each(function() {
-        var form = $(this.form);
-
-        // Cacher le champ ref et son label
-        var ref_field = form.find('[name=ref]');
-        ref_field.hide();
-        var ref_field_id = ref_field.attr('id');
-        if (ref_field_id) {
-            form.find('label[for=' + ref_field_id + ']').hide();
-        }
-
-        // On vérifie si le champ pays se trouve avant le champ à auto-compléter.
-        // Si c'est le cas, on va filtrer l'auto-complétion avec le pays
-        // sélectionné.
-        var all_inputs = form.find(':input');
-        var pays_input = all_inputs.filter('[name=pays]');
-        var pays_index = all_inputs.index(pays_input);
-        var my_index = all_inputs.index(this);
-        var critere_pays = false;
-        if (pays_index != -1 && pays_index < my_index) {
-            var critere_pays = pays_input.get();
-        }
-
-        // Pré-remplir les champs si une référence est déjà indiquée
-        var ref_id = form.find('[name=ref]').val();
-        if (ref_id) {
-            set_ref_etablissement(form, ref_id);
-        }
-
-        // Mettre en place l'autocomplete
-        $(this).autocomplete({
-            source: function(request, response) {
-                if (critere_pays) {
-                    request.pays = $(critere_pays).val();
-                }
-                $.getJSON('/references/autocomplete/etablissements.json', request, response);
-            },
-            select: function(event, ui) {
-                set_ref_etablissement(form, ui.item.id)
-            }
-        });
-    });
-
-});
diff --git a/auf/django/references/static/references/jquery.etablissement-autocomplete.js b/auf/django/references/static/references/jquery.etablissement-autocomplete.js
new file mode 100644 (file)
index 0000000..f9f3a84
--- /dev/null
@@ -0,0 +1,105 @@
+(function($) {
+
+    function set_ref_etablissement(form, id) {
+        form.find('[name=ref]').val(id);
+        $.get('/references/etablissements/' + id + '.json', function(data) {
+            for (field in data) {
+                if (field != 'id') {
+                    var widget = form.find('[name=' + field + ']');
+                    var value = $('<span class="etablissement-value"></span>');
+                    value.insertBefore(widget);
+                    if (widget.is(':checkbox')) {
+                        value.append('<img src="/static/references/icon-' +
+                                     (data[field] ? 'yes' : 'no') + '.gif" alt="' +
+                                     (data[field] ? 'oui' : 'non') + '/>');
+                        widget.attr('checked', data[field]);
+                    }
+                    else {
+                        value.insertBefore(widget);
+                        if (widget.is('select')) {
+                            value.append(widget.find('option[value=' + data[field] + ']').text());
+                        }
+                        else {
+                            value.append(data[field]);
+                        }
+                        widget.val(data[field]);
+                    }
+
+                    if (field == 'nom') {
+                        var button = $(
+                            '<button type="button" class="etablissement-change-button">' +
+                            'Modifier</button>'
+                        );
+                        value.append(' ');
+                        button.appendTo(value);
+                        button.click(function() { unset_ref_etablissement(form); })
+                    }
+                    widget.addClass('etablissement-hidden').hide();
+                    widget
+                        .next('.add-another,.datetimeshortcuts')
+                        .addClass('etablissement-hidden')
+                        .hide();
+                }
+            }
+        });
+    }
+
+    function unset_ref_etablissement(form) {
+        form.find('[name=ref]').val('');
+        form.find('[name=nom]').val('');
+        form.find('.etablissement-value').remove();
+        form.find('.etablissement-hidden').show();
+    }
+
+    $.fn.etablissement_autocomplete = function(exclude_refs) {
+
+        var form = this.closest('form');
+
+        // Cacher le champ ref et son label
+        var ref_field = form.find('[name=ref]');
+        ref_field.hide();
+        var ref_field_id = ref_field.attr('id');
+        if (ref_field_id) {
+            form.find('label[for=' + ref_field_id + ']').hide();
+        }
+
+        // On vérifie si le champ pays se trouve avant le champ à auto-compléter.
+        // Si c'est le cas, on va filtrer l'auto-complétion avec le pays
+        // sélectionné.
+        var all_inputs = form.find(':input');
+        var pays_input = all_inputs.filter('[name=pays]');
+        var pays_index = all_inputs.index(pays_input);
+        var my_index = all_inputs.index(this);
+        var critere_pays = false;
+        if (pays_index != -1 && pays_index < my_index) {
+            var critere_pays = pays_input.get();
+        }
+
+        // Pré-remplir les champs si une référence est déjà indiquée
+        var ref_id = form.find('[name=ref]').val();
+        if (ref_id) {
+            set_ref_etablissement(form, ref_id);
+        }
+
+        // Mettre en place l'autocomplete
+        this.autocomplete({
+            source: function(request, response) {
+                if (critere_pays) {
+                    request.pays = $(critere_pays).val();
+                }
+                if (exclude_refs) {
+                    request.exclude_refs = exclude_refs;
+                }
+                if (ref_id) {
+                    request.include = ref_id;
+                }
+                $.getJSON('/references/autocomplete/etablissements.json', request, response);
+            },
+            select: function(event, ui) {
+                set_ref_etablissement(form, ui.item.id)
+            }
+        });
+
+    }
+
+})(jQuery);
index 6a0bbdd..f31a03c 100644 (file)
@@ -1,3 +1,4 @@
+from django.db.models import Q
 from django.http import HttpResponse
 from django.utils import simplejson
 
 from django.http import HttpResponse
 from django.utils import simplejson
 
@@ -5,8 +6,15 @@ from auf.django.references import models as ref
 
 def autocomplete_etablissements(request):
     term = request.GET.get('term')
 
 def autocomplete_etablissements(request):
     term = request.GET.get('term')
+    exclude_refs = request.GET.get('exclude_refs')
+    include = request.GET.get('include')
     if term:
         etablissements = ref.Etablissement.objects.filter(nom__icontains=term)
     if term:
         etablissements = ref.Etablissement.objects.filter(nom__icontains=term)
+        if exclude_refs:
+            q = Q(**{str(exclude_refs): None})
+            if include:
+                q |= Q(id=include)
+            etablissements = etablissements.filter(q)
         pays = request.GET.get('pays')
         if pays:
             etablissements = etablissements.filter(pays=pays)
         pays = request.GET.get('pays')
         if pays:
             etablissements = etablissements.filter(pays=pays)