Auto-compléter le choix de l'établissement dans le formulaire d'inscription du
authorEric Mc Sween <eric.mcsween@gmail.com>
Sat, 4 Dec 2010 22:11:52 +0000 (17:11 -0500)
committerEric Mc Sween <eric.mcsween@gmail.com>
Sat, 4 Dec 2010 22:11:52 +0000 (17:11 -0500)
chercheur

13 files changed:
auf_savoirs_en_partage/chercheurs/forms.py
auf_savoirs_en_partage/chercheurs/models.py
auf_savoirs_en_partage/chercheurs/views.py
auf_savoirs_en_partage/media/css/global.css
auf_savoirs_en_partage/media/css/jquery-ui/images/ui-bg_diagonal-maze_20_6e4f1c_10x10.png
auf_savoirs_en_partage/media/css/jquery-ui/images/ui-bg_fine-grain_10_eceadf_60x60.png
auf_savoirs_en_partage/media/css/jquery-ui/images/ui-bg_fine-grain_68_b83400_60x60.png
auf_savoirs_en_partage/media/css/jquery-ui/images/ui-icons_8c291d_256x240.png
auf_savoirs_en_partage/media/css/jquery-ui/jquery-ui.css
auf_savoirs_en_partage/media/js/chercheur_edit.js
auf_savoirs_en_partage/media/js/jquery-ui.js
auf_savoirs_en_partage/templates/chercheurs/chercheur_form.html
auf_savoirs_en_partage/urls.py

index a6ad47a..668e388 100644 (file)
@@ -47,9 +47,6 @@ class PersonneInscriptionForm(PersonneForm):
 
 class ChercheurForm(forms.ModelForm):
     """Formulaire d'édition d'un chercheur."""
-    ETABLISSEMENT_CHOICES = ((id, nom if len(nom) < 80 else nom[:80] + '...')
-                             for id, nom in Etablissement.objects.filter(membre=True).values_list('id', 'nom'))
-
     membre_instance_auf = forms.ChoiceField(
         label="Êtes-vous (ou avez-vous déjà été) membre d'une instance de l'AUF?",
         help_text="e.g. conseil scientifique, conseil associatif, commission régionale d'experts",
@@ -75,7 +72,8 @@ class ChercheurForm(forms.ModelForm):
     membre_reseau_institutionnel_details = forms.CharField(required=False, label="Préciser lesquelles et votre fonction")
     membre_reseau_institutionnel_dates = forms.CharField(required=False, label="Préciser les dates")
 
-    etablissement = forms.ChoiceField(label='Etablissement', required=False, choices=chain([('', '---------')], ETABLISSEMENT_CHOICES))
+    etablissement = forms.CharField(label='Etablissement', required=True)
+    pays_etablissement = forms.ModelChoiceField(label='Pays', queryset=Pays.objects.all(), required=True)
 
     expertises_auf = forms.ChoiceField(
         label="Êtes-vous disposé à réaliser des expertises pour l'AUF?",
@@ -90,17 +88,45 @@ class ChercheurForm(forms.ModelForm):
 
     class Meta:
         model = Chercheur
-        fields = ('statut', 'diplome', 'etablissement',
-                  'etablissement_autre_nom', 'etablissement_autre_pays',
-                  'discipline', 'theme_recherche', 'groupe_recherche', 'mots_cles',
-                  'url_site_web', 'url_blog', 'url_reseau_social',
-                  'membre_instance_auf', 'membre_instance_auf_details', 'membre_instance_auf_dates',
-                  'expert_oif', 'expert_oif_details', 'expert_oif_dates',
+        fields = ('statut', 'diplome', 'discipline', 'theme_recherche',
+                  'groupe_recherche', 'mots_cles', 'url_site_web',
+                  'url_blog', 'url_reseau_social', 'membre_instance_auf',
+                  'membre_instance_auf_details',
+                  'membre_instance_auf_dates', 'expert_oif',
+                  'expert_oif_details', 'expert_oif_dates',
                   'membre_association_francophone',
                   'membre_association_francophone_details',
-                  'membre_reseau_institutionnel', 'membre_reseau_institutionnel_details',
+                  'membre_reseau_institutionnel',
+                  'membre_reseau_institutionnel_details',
                   'membre_reseau_institutionnel_dates', 'expertises_auf')
         
+    def __init__(self, data=None, prefix=None, instance=None):
+        if instance is not None:
+            initial = {}
+            if instance.etablissement:
+                initial['etablissement'] = instance.etablissement.nom
+                initial['pays_etablissement'] = instance.etablissement.pays_id
+            else:
+                initial['etablissement'] = instance.etablissement_autre_nom
+                initial['pays_etablissement'] = instance.etablissement_autre_pays_id
+        else:
+            initial = None
+        super(ChercheurForm, self).__init__(data=data, prefix=prefix, instance=instance, initial=initial)
+
+    def save(self):
+        nom_etablissement = self.cleaned_data['etablissement']
+        pays_etablissement = self.cleaned_data['pays_etablissement']
+        try:
+            etablissement = Etablissement.objects.get(nom=nom_etablissement, pays=pays_etablissement)
+            self.instance.etablissement = etablissement
+            self.instance.etablissement_autre = ''
+            self.instance.etablissement_autre_pays = None
+        except Etablissement.DoesNotExist:
+            self.instance.etablissement = None
+            self.instance.etablissement_autre_nom = nom_etablissement
+            self.instance.etablissement_autre_pays = pays_etablissement
+        super(ChercheurForm, self).save()
+
     def clean_membre_instance_auf(self):
         return bool(int(self.cleaned_data['membre_instance_auf']))
     
@@ -162,25 +188,9 @@ class ChercheurForm(forms.ModelForm):
             raise forms.ValidationError('Veuillez préciser les dates')
         return dates
 
-    def clean_etablissement(self):
-        etablissement = self.cleaned_data['etablissement']
-        if etablissement:
-            return Etablissement.objects.get(id=etablissement)
-
     def clean_expertises_auf(self):
         return bool(int(self.cleaned_data['expertises_auf']))
 
-    def clean(self):
-        etablissement = self.cleaned_data['etablissement']
-        etablissement_autre_nom = self.cleaned_data['etablissement_autre_nom']
-        etablissement_autre_pays = self.cleaned_data['etablissement_autre_pays']
-        if not etablissement:
-            if not etablissement_autre_nom:
-                self._errors['etablissement'] = self.error_class([u"Vous devez renseigner l'établissement"])
-            elif not etablissement_autre_pays:
-                self._errors['etablissement_autre_pays'] = self.error_class([u"Vous devez renseigner le pays de l'établissement"])
-        return self.cleaned_data
-
 class ChercheurInscriptionForm(ChercheurForm):
     attestation = forms.BooleanField(
         required=True, 
index 28b11a6..e6b8643 100644 (file)
@@ -154,10 +154,13 @@ class Chercheur(models.Model):
     discipline = models.ForeignKey(Discipline, db_column='discipline', null=True, verbose_name='Discipline')
     theme_recherche = models.TextField(null=True, blank=True, verbose_name='thèmes de recherche')                                    
     groupe_recherche = models.CharField(max_length=255, blank=True, verbose_name='groupe de recherche')
-    url_site_web = models.URLField(max_length=255, null=True, blank=True, verbose_name='adresse site Internet')
-    url_blog = models.URLField(max_length=255, null=True, blank=True, verbose_name='blog')
+    url_site_web = models.URLField(max_length=255, null=True, blank=True, 
+                                   verbose_name='adresse site Internet', verify_exists=False)
+    url_blog = models.URLField(max_length=255, null=True, blank=True, verbose_name='blog',
+                               verify_exists=False)
     url_reseau_social = models.URLField(
         max_length=255, null=True, blank=True, verbose_name='Réseau social',
+        verify_exists=False,
         help_text=u"Vous pouvez indiquer ici l'adresse de votre page personnelle dans votre réseau social préféré (e.g. Facebook, LinkedIn, Twitter, Identica, ...)"
     )
                                     
index 766c0eb..933a4ad 100644 (file)
@@ -7,6 +7,7 @@ from django.template.loader import get_template
 from django.core.urlresolvers import reverse as url
 from django.core.mail import send_mail
 from django.conf import settings
+from django.utils import simplejson
 from django.views.decorators.cache import never_cache
 
 from forms import *
@@ -219,3 +220,17 @@ def conversion(request):
     return render_to_response("chercheurs/conversion.html", {}, 
                               context_instance=RequestContext(request))
 
+def etablissements_autocomplete(request):
+    term = request.GET.get('term')
+    noms = list(Etablissement.objects.filter(nom__icontains=term).values_list('nom', flat=True)[:20])
+    json = simplejson.dumps(noms)
+    return HttpResponse(json, mimetype='application/json')
+
+def etablissements_pays(request):
+    etablissement = request.GET.get('etablissement')
+    try:
+        pays = Etablissement.objects.get(nom=etablissement).pays_id
+    except Etablissement.DoesNotExist:
+        pays = None
+    json = simplejson.dumps(pays)
+    return HttpResponse(json, mimetype='application/json')
index d391638..95c0742 100644 (file)
@@ -21,7 +21,7 @@ LIGNES grises -> #e0e0e0 et #d5d5d5
 html { height:100%; }
 body { height:100%; font-size: 85%; line-height:1.4; color:#3a3125; 
        background:#fff url(../img/background-body.jpg) repeat-y 50% 0; 
-       font-family:Verdana, Arial, Sans-Serif; text-align:center; }
+       font-family:Verdana, Arial, Sans-Serif; }
 a, a:active {text-decoration:underline;color:#97012c;}
 a:visited {color:#97012c;}
 a:hover {color:#97012c;}
index 83cf468..1bb13a2 100644 (file)
Binary files a/auf_savoirs_en_partage/media/css/jquery-ui/images/ui-bg_diagonal-maze_20_6e4f1c_10x10.png and b/auf_savoirs_en_partage/media/css/jquery-ui/images/ui-bg_diagonal-maze_20_6e4f1c_10x10.png differ
index 4656742..a14a0d7 100644 (file)
Binary files a/auf_savoirs_en_partage/media/css/jquery-ui/images/ui-bg_fine-grain_10_eceadf_60x60.png and b/auf_savoirs_en_partage/media/css/jquery-ui/images/ui-bg_fine-grain_10_eceadf_60x60.png differ
index 4e19798..3f3639b 100644 (file)
Binary files a/auf_savoirs_en_partage/media/css/jquery-ui/images/ui-bg_fine-grain_68_b83400_60x60.png and b/auf_savoirs_en_partage/media/css/jquery-ui/images/ui-bg_fine-grain_68_b83400_60x60.png differ
index 961c8fe..a90f0ce 100644 (file)
Binary files a/auf_savoirs_en_partage/media/css/jquery-ui/images/ui-icons_8c291d_256x240.png and b/auf_savoirs_en_partage/media/css/jquery-ui/images/ui-icons_8c291d_256x240.png differ
index bc7043c..7b8c830 100644 (file)
 /* Overlays */
 .ui-widget-overlay { background: #6e4f1c url(images/ui-bg_diagonal-maze_20_6e4f1c_10x10.png) 50% 50% repeat; opacity: .60;filter:Alpha(Opacity=60); }
 .ui-widget-shadow { margin: 0 0 0 -10px; padding: 5px; background: #000000 url(images/ui-bg_diagonal-maze_40_000000_10x10.png) 50% 50% repeat; opacity: .60;filter:Alpha(Opacity=60); -moz-border-radius: 18px; -webkit-border-radius: 18px; border-radius: 18px; }/*
+ * jQuery UI Autocomplete 1.8.6
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Autocomplete#theming
+ */
+.ui-autocomplete { position: absolute; cursor: default; }      
+
+/* workarounds */
+* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
+
+/*
+ * jQuery UI Menu 1.8.6
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Menu#theming
+ */
+.ui-menu {
+       list-style:none;
+       padding: 2px;
+       margin: 0;
+       display:block;
+       float: left;
+}
+.ui-menu .ui-menu {
+       margin-top: -3px;
+}
+.ui-menu .ui-menu-item {
+       margin:0;
+       padding: 0;
+       zoom: 1;
+       float: left;
+       clear: left;
+       width: 100%;
+}
+.ui-menu .ui-menu-item a {
+       text-decoration:none;
+       display:block;
+       padding:.2em .4em;
+       line-height:1.5;
+       zoom:1;
+}
+.ui-menu .ui-menu-item a.ui-state-hover,
+.ui-menu .ui-menu-item a.ui-state-active {
+       font-weight: normal;
+       margin: -1px;
+}
+/*
  * jQuery UI Datepicker 1.8.6
  *
  * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
index 9097d30..9714c81 100644 (file)
@@ -1,14 +1,5 @@
 (function() {
 
-    function update_etablissement_autre() {
-        if ($('#id_chercheur-etablissement').val() == '') {
-            $('#etablissement_autre').slideDown('fast');
-        }
-        else {
-            $('#etablissement_autre').slideUp('fast');
-        }
-    }
-
     $(document).ready(function() {
         $('#expertises fieldset').formset({
             prefix: 'expertise',
             deleteText: 'supprimer cette publication',
             formCssClass: 'dynamic-form-publications'
         });
-        update_etablissement_autre()
-        $('#id_chercheur-etablissement').change(update_etablissement_autre)
+        $('input[name=chercheur-etablissement]').autocomplete({ 
+            source: '/etablissements/autocomplete/',
+            select: function(event, ui) {
+                var etablissement = ui.item.value;
+                $.getJSON(
+                    '/etablissements/pays/', 
+                    { etablissement: etablissement },
+                    function(pays) {
+                        $('select[name=chercheur-pays_etablissement]').val(pays);
+                    }
+                );
+            }
+        });
     });
+
 })();
index 468f0f6..332604a 100644 (file)
@@ -15,6 +15,68 @@ if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"),10);i
 d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){var b=a.nodeName.toLowerCase(),d=c.attr(a,"tabindex");if("area"===b){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&k(a)}return(/input|select|textarea|button|object/.test(b)?!a.disabled:"a"==b?a.href||!isNaN(d):!isNaN(d))&&k(a)},tabbable:function(a){var b=c.attr(a,"tabindex");return(isNaN(b)||b>=0)&&c(a).is(":focusable")}});
 c(function(){var a=document.body,b=a.appendChild(b=document.createElement("div"));c.extend(b.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.offsetHeight===100;c.support.selectstart="onselectstart"in b;a.removeChild(b).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&a.element[0].parentNode)for(var e=0;e<b.length;e++)a.options[b[e][0]]&&
 b[e][1].apply(a.element,d)}},contains:function(a,b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(a,b){if(c(a).css("overflow")==="hidden")return false;b=b&&b==="left"?"scrollLeft":"scrollTop";var d=false;if(a[b]>0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a<b+d},isOver:function(a,b,d,e,h,i){return c.ui.isOverAxis(a,d,h)&&c.ui.isOverAxis(b,e,i)}})}})(jQuery);
+;/*!
+ * jQuery UI Widget 1.8.6
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Widget
+ */
+(function(b,j){if(b.cleanData){var k=b.cleanData;b.cleanData=function(a){for(var c=0,d;(d=a[c])!=null;c++)b(d).triggerHandler("remove");k(a)}}else{var l=b.fn.remove;b.fn.remove=function(a,c){return this.each(function(){if(!c)if(!a||b.filter(a,[this]).length)b("*",this).add([this]).each(function(){b(this).triggerHandler("remove")});return l.call(b(this),a,c)})}}b.widget=function(a,c,d){var e=a.split(".")[0],f;a=a.split(".")[1];f=e+"-"+a;if(!d){d=c;c=b.Widget}b.expr[":"][f]=function(h){return!!b.data(h,
+a)};b[e]=b[e]||{};b[e][a]=function(h,g){arguments.length&&this._createWidget(h,g)};c=new c;c.options=b.extend(true,{},c.options);b[e][a].prototype=b.extend(true,c,{namespace:e,widgetName:a,widgetEventPrefix:b[e][a].prototype.widgetEventPrefix||a,widgetBaseClass:f},d);b.widget.bridge(a,b[e][a])};b.widget.bridge=function(a,c){b.fn[a]=function(d){var e=typeof d==="string",f=Array.prototype.slice.call(arguments,1),h=this;d=!e&&f.length?b.extend.apply(null,[true,d].concat(f)):d;if(e&&d.charAt(0)==="_")return h;
+e?this.each(function(){var g=b.data(this,a),i=g&&b.isFunction(g[d])?g[d].apply(g,f):g;if(i!==g&&i!==j){h=i;return false}}):this.each(function(){var g=b.data(this,a);g?g.option(d||{})._init():b.data(this,a,new c(d,this))});return h}};b.Widget=function(a,c){arguments.length&&this._createWidget(a,c)};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(a,c){b.data(c,this.widgetName,this);this.element=b(c);this.options=b.extend(true,{},this.options,
+this._getCreateOptions(),a);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},
+widget:function(){return this.element},option:function(a,c){var d=a;if(arguments.length===0)return b.extend({},this.options);if(typeof a==="string"){if(c===j)return this.options[a];d={};d[a]=c}this._setOptions(d);return this},_setOptions:function(a){var c=this;b.each(a,function(d,e){c._setOption(d,e)});return this},_setOption:function(a,c){this.options[a]=c;if(a==="disabled")this.widget()[c?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",c);return this},
+enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(a,c,d){var e=this.options[a];c=b.Event(c);c.type=(a===this.widgetEventPrefix?a:this.widgetEventPrefix+a).toLowerCase();d=d||{};if(c.originalEvent){a=b.event.props.length;for(var f;a;){f=b.event.props[--a];c[f]=c.originalEvent[f]}}this.element.trigger(c,d);return!(b.isFunction(e)&&e.call(this.element[0],c,d)===false||c.isDefaultPrevented())}}})(jQuery);
+;/*
+ * jQuery UI Position 1.8.6
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Position
+ */
+(function(c){c.ui=c.ui||{};var n=/left|center|right/,o=/top|center|bottom/,t=c.fn.position,u=c.fn.offset;c.fn.position=function(b){if(!b||!b.of)return t.apply(this,arguments);b=c.extend({},b);var a=c(b.of),d=a[0],g=(b.collision||"flip").split(" "),e=b.offset?b.offset.split(" "):[0,0],h,k,j;if(d.nodeType===9){h=a.width();k=a.height();j={top:0,left:0}}else if(d.setTimeout){h=a.width();k=a.height();j={top:a.scrollTop(),left:a.scrollLeft()}}else if(d.preventDefault){b.at="left top";h=k=0;j={top:b.of.pageY,
+left:b.of.pageX}}else{h=a.outerWidth();k=a.outerHeight();j=a.offset()}c.each(["my","at"],function(){var f=(b[this]||"").split(" ");if(f.length===1)f=n.test(f[0])?f.concat(["center"]):o.test(f[0])?["center"].concat(f):["center","center"];f[0]=n.test(f[0])?f[0]:"center";f[1]=o.test(f[1])?f[1]:"center";b[this]=f});if(g.length===1)g[1]=g[0];e[0]=parseInt(e[0],10)||0;if(e.length===1)e[1]=e[0];e[1]=parseInt(e[1],10)||0;if(b.at[0]==="right")j.left+=h;else if(b.at[0]==="center")j.left+=h/2;if(b.at[1]==="bottom")j.top+=
+k;else if(b.at[1]==="center")j.top+=k/2;j.left+=e[0];j.top+=e[1];return this.each(function(){var f=c(this),l=f.outerWidth(),m=f.outerHeight(),p=parseInt(c.curCSS(this,"marginLeft",true))||0,q=parseInt(c.curCSS(this,"marginTop",true))||0,v=l+p+parseInt(c.curCSS(this,"marginRight",true))||0,w=m+q+parseInt(c.curCSS(this,"marginBottom",true))||0,i=c.extend({},j),r;if(b.my[0]==="right")i.left-=l;else if(b.my[0]==="center")i.left-=l/2;if(b.my[1]==="bottom")i.top-=m;else if(b.my[1]==="center")i.top-=m/2;
+i.left=parseInt(i.left);i.top=parseInt(i.top);r={left:i.left-p,top:i.top-q};c.each(["left","top"],function(s,x){c.ui.position[g[s]]&&c.ui.position[g[s]][x](i,{targetWidth:h,targetHeight:k,elemWidth:l,elemHeight:m,collisionPosition:r,collisionWidth:v,collisionHeight:w,offset:e,my:b.my,at:b.at})});c.fn.bgiframe&&f.bgiframe();f.offset(c.extend(i,{using:b.using}))})};c.ui.position={fit:{left:function(b,a){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();b.left=d>0?
+b.left-d:Math.max(b.left-a.collisionPosition.left,b.left)},top:function(b,a){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();b.top=d>0?b.top-d:Math.max(b.top-a.collisionPosition.top,b.top)}},flip:{left:function(b,a){if(a.at[0]!=="center"){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();var g=a.my[0]==="left"?-a.elemWidth:a.my[0]==="right"?a.elemWidth:0,e=a.at[0]==="left"?a.targetWidth:-a.targetWidth,h=-2*a.offset[0];b.left+=
+a.collisionPosition.left<0?g+e+h:d>0?g+e+h:0}},top:function(b,a){if(a.at[1]!=="center"){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();var g=a.my[1]==="top"?-a.elemHeight:a.my[1]==="bottom"?a.elemHeight:0,e=a.at[1]==="top"?a.targetHeight:-a.targetHeight,h=-2*a.offset[1];b.top+=a.collisionPosition.top<0?g+e+h:d>0?g+e+h:0}}}};if(!c.offset.setOffset){c.offset.setOffset=function(b,a){if(/static/.test(c.curCSS(b,"position")))b.style.position="relative";var d=c(b),
+g=d.offset(),e=parseInt(c.curCSS(b,"top",true),10)||0,h=parseInt(c.curCSS(b,"left",true),10)||0;g={top:a.top-g.top+e,left:a.left-g.left+h};"using"in a?a.using.call(b,g):d.css(g)};c.fn.offset=function(b){var a=this[0];if(!a||!a.ownerDocument)return null;if(b)return this.each(function(){c.offset.setOffset(this,b)});return u.call(this)}}})(jQuery);
+;/*
+ * jQuery UI Autocomplete 1.8.6
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Autocomplete
+ *
+ * Depends:
+ *     jquery.ui.core.js
+ *     jquery.ui.widget.js
+ *     jquery.ui.position.js
+ */
+(function(e){e.widget("ui.autocomplete",{options:{appendTo:"body",delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},_create:function(){var a=this,b=this.element[0].ownerDocument,f;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(!(a.options.disabled||a.element.attr("readonly"))){f=false;var d=e.ui.keyCode;switch(c.keyCode){case d.PAGE_UP:a._move("previousPage",
+c);break;case d.PAGE_DOWN:a._move("nextPage",c);break;case d.UP:a._move("previous",c);c.preventDefault();break;case d.DOWN:a._move("next",c);c.preventDefault();break;case d.ENTER:case d.NUMPAD_ENTER:if(a.menu.active){f=true;c.preventDefault()}case d.TAB:if(!a.menu.active)return;a.menu.select(c);break;case d.ESCAPE:a.element.val(a.term);a.close(c);break;default:clearTimeout(a.searching);a.searching=setTimeout(function(){if(a.term!=a.element.val()){a.selectedItem=null;a.search(null,c)}},a.options.delay);
+break}}}).bind("keypress.autocomplete",function(c){if(f){f=false;c.preventDefault()}}).bind("focus.autocomplete",function(){if(!a.options.disabled){a.selectedItem=null;a.previous=a.element.val()}}).bind("blur.autocomplete",function(c){if(!a.options.disabled){clearTimeout(a.searching);a.closing=setTimeout(function(){a.close(c);a._change(c)},150)}});this._initSource();this.response=function(){return a._response.apply(a,arguments)};this.menu=e("<ul></ul>").addClass("ui-autocomplete").appendTo(e(this.options.appendTo||
+"body",b)[0]).mousedown(function(c){var d=a.menu.element[0];e(c.target).closest(".ui-menu-item").length||setTimeout(function(){e(document).one("mousedown",function(g){g.target!==a.element[0]&&g.target!==d&&!e.ui.contains(d,g.target)&&a.close()})},1);setTimeout(function(){clearTimeout(a.closing)},13)}).menu({focus:function(c,d){d=d.item.data("item.autocomplete");false!==a._trigger("focus",c,{item:d})&&/^key/.test(c.originalEvent.type)&&a.element.val(d.value)},selected:function(c,d){d=d.item.data("item.autocomplete");
+var g=a.previous;if(a.element[0]!==b.activeElement){a.element.focus();a.previous=g;setTimeout(function(){a.previous=g},1)}false!==a._trigger("select",c,{item:d})&&a.element.val(d.value);a.term=a.element.val();a.close(c);a.selectedItem=d},blur:function(){a.menu.element.is(":visible")&&a.element.val()!==a.term&&a.element.val(a.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu");e.fn.bgiframe&&this.menu.element.bgiframe()},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup");
+this.menu.element.remove();e.Widget.prototype.destroy.call(this)},_setOption:function(a,b){e.Widget.prototype._setOption.apply(this,arguments);a==="source"&&this._initSource();if(a==="appendTo")this.menu.element.appendTo(e(b||"body",this.element[0].ownerDocument)[0])},_initSource:function(){var a=this,b,f;if(e.isArray(this.options.source)){b=this.options.source;this.source=function(c,d){d(e.ui.autocomplete.filter(b,c.term))}}else if(typeof this.options.source==="string"){f=this.options.source;this.source=
+function(c,d){a.xhr&&a.xhr.abort();a.xhr=e.getJSON(f,c,function(g,i,h){h===a.xhr&&d(g);a.xhr=null})}}else this.source=this.options.source},search:function(a,b){a=a!=null?a:this.element.val();this.term=this.element.val();if(a.length<this.options.minLength)return this.close(b);clearTimeout(this.closing);if(this._trigger("search",b)!==false)return this._search(a)},_search:function(a){this.element.addClass("ui-autocomplete-loading");this.source({term:a},this.response)},_response:function(a){if(a&&a.length){a=
+this._normalize(a);this._suggest(a);this._trigger("open")}else this.close();this.element.removeClass("ui-autocomplete-loading")},close:function(a){clearTimeout(this.closing);if(this.menu.element.is(":visible")){this._trigger("close",a);this.menu.element.hide();this.menu.deactivate()}},_change:function(a){this.previous!==this.element.val()&&this._trigger("change",a,{item:this.selectedItem})},_normalize:function(a){if(a.length&&a[0].label&&a[0].value)return a;return e.map(a,function(b){if(typeof b===
+"string")return{label:b,value:b};return e.extend({label:b.label||b.value,value:b.value||b.label},b)})},_suggest:function(a){this._renderMenu(this.menu.element.empty().zIndex(this.element.zIndex()+1),a);this.menu.deactivate();this.menu.refresh();this.menu.element.show().position(e.extend({of:this.element},this.options.position));this._resizeMenu()},_resizeMenu:function(){var a=this.menu.element;a.outerWidth(Math.max(a.width("").outerWidth(),this.element.outerWidth()))},_renderMenu:function(a,b){var f=
+this;e.each(b,function(c,d){f._renderItem(a,d)})},_renderItem:function(a,b){return e("<li></li>").data("item.autocomplete",b).append(e("<a></a>").text(b.label)).appendTo(a)},_move:function(a,b){if(this.menu.element.is(":visible"))if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term);this.menu.deactivate()}else this.menu[a](b);else this.search(null,b)},widget:function(){return this.menu.element}});e.extend(e.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,
+"\\$&")},filter:function(a,b){var f=new RegExp(e.ui.autocomplete.escapeRegex(b),"i");return e.grep(a,function(c){return f.test(c.label||c.value||c)})}})})(jQuery);
+(function(e){e.widget("ui.menu",{_create:function(){var a=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(b){if(e(b.target).closest(".ui-menu-item a").length){b.preventDefault();a.select(b)}});this.refresh()},refresh:function(){var a=this;this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem").children("a").addClass("ui-corner-all").attr("tabindex",
+-1).mouseenter(function(b){a.activate(b,e(this).parent())}).mouseleave(function(){a.deactivate()})},activate:function(a,b){this.deactivate();if(this.hasScroll()){var f=b.offset().top-this.element.offset().top,c=this.element.attr("scrollTop"),d=this.element.height();if(f<0)this.element.attr("scrollTop",c+f);else f>=d&&this.element.attr("scrollTop",c+f-d+b.height())}this.active=b.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end();this._trigger("focus",a,{item:b})},
+deactivate:function(){if(this.active){this.active.children("a").removeClass("ui-state-hover").removeAttr("id");this._trigger("blur");this.active=null}},next:function(a){this.move("next",".ui-menu-item:first",a)},previous:function(a){this.move("prev",".ui-menu-item:last",a)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(a,b,f){if(this.active){a=this.active[a+"All"](".ui-menu-item").eq(0);
+a.length?this.activate(f,a):this.activate(f,this.element.children(b))}else this.activate(f,this.element.children(b))},nextPage:function(a){if(this.hasScroll())if(!this.active||this.last())this.activate(a,this.element.children(".ui-menu-item:first"));else{var b=this.active.offset().top,f=this.element.height(),c=this.element.children(".ui-menu-item").filter(function(){var d=e(this).offset().top-b-f+e(this).height();return d<10&&d>-10});c.length||(c=this.element.children(".ui-menu-item:last"));this.activate(a,
+c)}else this.activate(a,this.element.children(".ui-menu-item").filter(!this.active||this.last()?":first":":last"))},previousPage:function(a){if(this.hasScroll())if(!this.active||this.first())this.activate(a,this.element.children(".ui-menu-item:last"));else{var b=this.active.offset().top,f=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var c=e(this).offset().top-b+f-e(this).height();return c<10&&c>-10});result.length||(result=this.element.children(".ui-menu-item:first"));
+this.activate(a,result)}else this.activate(a,this.element.children(".ui-menu-item").filter(!this.active||this.first()?":last":":first"))},hasScroll:function(){return this.element.height()<this.element.attr("scrollHeight")},select:function(a){this._trigger("selected",a,{item:this.active})}})})(jQuery);
 ;/*
  * jQuery UI Datepicker 1.8.6
  *
index 5695d13..068c632 100644 (file)
     <legend>Etablissement de rattachement <span style="color:red">*</span></legend>
     <table>
         {% form_field forms.chercheur.etablissement %}
+        {% form_field forms.chercheur.pays_etablissement %}
     </table>
-    <div id="etablissement_autre">
-        <p>Si l'établissement n'existe pas dans la liste des établissements membres de l'AUF, ci-dessus</p>
-        <table>
-            {% form_field forms.chercheur.etablissement_autre_nom %}
-            {% form_field forms.chercheur.etablissement_autre_pays %}
-        </table>
-    </div>
 </fieldset>
 
 <fieldset>
index e7fd3d7..6505039 100644 (file)
@@ -72,6 +72,8 @@ urlpatterns = sep_patterns + patterns(
     (r'^accounts/login/$', 'chercheurs.views.chercheur_login'),
     (r'^accounts/change_password/$', 'chercheurs.views.change_password'),
     (r'^accounts/send_password/$', 'chercheurs.views.send_password'),
+    (r'^etablissements/autocomplete/$', 'chercheurs.views.etablissements_autocomplete'),
+    (r'^etablissements/pays/$', 'chercheurs.views.etablissements_pays'),
 
     # section par discipline et/ou région
     (r'^discipline/(?P<discipline>\d+)/', include(sep_patterns)),