Un chercheur peut maintenant avoir plusieurs expertises.
authorEric Mc Sween <eric.mcsween@gmail.com>
Tue, 9 Nov 2010 21:47:16 +0000 (16:47 -0500)
committerEric Mc Sween <eric.mcsween@gmail.com>
Tue, 9 Nov 2010 21:47:16 +0000 (16:47 -0500)
Demande #721.

auf_savoirs_en_partage/chercheurs/forms.py
auf_savoirs_en_partage/chercheurs/models.py
auf_savoirs_en_partage/media/css/global.css
auf_savoirs_en_partage/media/js/chercheur_edit.js [new file with mode: 0644]
auf_savoirs_en_partage/media/js/jquery.formset.js [new file with mode: 0644]
auf_savoirs_en_partage/sql/2010-11-09a.sql [new file with mode: 0644]
auf_savoirs_en_partage/templates/chercheurs/chercheur_form.html
auf_savoirs_en_partage/templates/chercheurs/edit.html
auf_savoirs_en_partage/templates/chercheurs/fiche.html
auf_savoirs_en_partage/templates/chercheurs/inscription.html

index 329c877..e971d04 100644 (file)
@@ -2,6 +2,7 @@
 import hashlib
 from django import forms
 from django.db.models import Q
+from django.forms.models import inlineformset_factory
 from itertools import chain
 from models import *
 
@@ -132,6 +133,8 @@ class ExpertiseForm(forms.ModelForm):
         value = self.cleaned_data['organisme_demandeur_visible']
         return bool(int(value)) if value else False
 
+ExpertiseFormSet = inlineformset_factory(Chercheur, Expertise, form=ExpertiseForm, extra=1)
+
 class ChercheurFormGroup(object):
     """Groupe de formulaires nécessaires pour l'inscription et l'édition
        d'un chercheur."""
@@ -146,19 +149,19 @@ class ChercheurFormGroup(object):
         self.publication3 = PublicationForm(data=data, prefix='publication3', instance=chercheur and chercheur.publication3)
         self.publication4 = PublicationForm(data=data, prefix='publication4', instance=chercheur and chercheur.publication4)
         self.these = TheseForm(data=data, prefix='these', instance=chercheur and chercheur.these)
-        self.expertise = ExpertiseForm(data=data, prefix='expertise', instance=chercheur and chercheur.expertise)
+        self.expertises = ExpertiseFormSet(data=data, prefix='expertise', instance=chercheur)
 
     @property
     def has_errors(self):
         return bool(self.chercheur.errors or self.personne.errors or self.groupes.errors or
                     self.publication1.errors or self.publication2.errors or self.publication3.errors or
-                    self.publication4.errors or self.these.errors or self.expertise.errors)
+                    self.publication4.errors or self.these.errors or self.expertises.errors)
 
     def is_valid(self):
         return self.chercheur.is_valid() and self.personne.is_valid() and self.groupes.is_valid() and \
                self.publication1.is_valid() and self.publication2.is_valid() and \
                self.publication3.is_valid() and self.publication4.is_valid() and \
-               self.these.is_valid() and self.expertise.is_valid()
+               self.these.is_valid() and self.expertises.is_valid()
 
     def save(self):
         if self.is_valid():
@@ -177,8 +180,7 @@ class ChercheurFormGroup(object):
             if self.publication4.cleaned_data['titre']:
                 chercheur.publication4 = self.publication4.save()
             chercheur.these = self.these.save()
-            if self.expertise.cleaned_data['nom']:
-                chercheur.expertise = self.expertise.save()
+            self.expertises.save()
 
             # Puis enregistrer le chercheur lui-même.
             self.chercheur.save()
@@ -220,7 +222,7 @@ class RepertoireSearchForm (forms.Form):
             statut = self.cleaned_data["statut"]
             if statut:
                 if statut == "expert":
-                    qs = qs.exclude(expertise=None)
+                    qs = qs.exclude(expertises=None)
                 else:
                     qs = qs.filter(statut=statut)
             pays = self.cleaned_data["pays"]
index 56506d4..13b59a8 100644 (file)
@@ -109,7 +109,6 @@ 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ème de recherche')                                    
     groupe_recherche = models.CharField(max_length=255, blank=True, verbose_name='groupe de recherche')
-    expertise = models.ForeignKey('Expertise', db_column='expertise', null=True, blank=True, related_name='expertise')
     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_reseau_social = models.URLField(
@@ -202,9 +201,10 @@ class Publication(models.Model):
         
 class Expertise(models.Model):
     id = models.AutoField(primary_key=True, db_column='id')
-    nom = models.CharField(max_length=255, null=True, blank=True, verbose_name = 'Objet de la dernière expertise')
+    chercheur = models.ForeignKey(Chercheur, related_name='expertises')
+    nom = models.CharField(max_length=255, null=True, blank=True, verbose_name = "Objet de l'expertise")
     date = models.CharField(max_length=255, blank=True)
-    lieu = models.CharField(max_length=255, null=True, blank=True, verbose_name = 'Lieu de la dernière expertise')
+    lieu = models.CharField(max_length=255, null=True, blank=True, verbose_name = "Lieu de l'expertise")
     organisme_demandeur = models.CharField(max_length=255, null=True, blank=True, verbose_name = 'Organisme demandeur')
     organisme_demandeur_visible = models.BooleanField(verbose_name="Afficher l'organisme demandeur")
     actif = models.BooleanField(editable = False, db_column='actif')
index 356be78..e69f824 100644 (file)
@@ -43,6 +43,7 @@ sup{font-size: smaller; vertical-align: 0.5em; line-height: 1px;}
 
 td ul { margin: 0 }
 
+form { padding-right:20px; margin: 1em 0; }
 form td { vertical-align: top }
 form th { width: 20em; text-align: left; font-weight: bold }
 form table { width: 100% }
@@ -50,6 +51,20 @@ form input[type=text] { width: 20em }
 form input.date { width: auto }
 form select { width: 80%; overflow: hidden }
 form p { margin-bottom: 2px }
+fieldset { clear: both; padding: 10px; margin: 0 0 0 0; position: relative }
+fieldset { border-color: #000000; border-width: 1px 0 0 0; border-style: solid none none none; }
+fieldset { font-size: 100%; }
+fieldset fieldset { border: 1px solid #ccc; background: #fafafa; margin: 10px }
+legend { font-size: 150%; font-weight: bold; color: #000000; margin: 0 0 0 0; padding: 0 5px; }
+
+label {
+  font-size: 12px;
+}
+td, th
+{
+vertical-align:middle;
+}
+
 
 .box { padding:0 0 20px 0; }
 .lbl {color: #97012c; }
@@ -132,7 +147,7 @@ div.boite-recherche p a:hover { color:#97012c; text-decoration:none;}
 #contenu .demi-gauche img.top { height:9px; position:relative; top:-9px;}
 #contenu .demi-gauche img.bottom { height:9px;  position:relative; bottom:-9px;}
 
-.contenu-wrapper { padding:0 0 0 25px; }
+.contenu-wrapper { padding: 0 25px; }
 
 ul a { text-decoration:none; }
 ul a:hover { text-decoration:underline; }
@@ -205,34 +220,6 @@ ul.actions { position: absolute; top: 15px; right: 20px; width: 240px; }
 #agenda, #actualites {position: relative;}
 #rss-agenda, #rss-actualites {position: absolute; right: 26px; top: 10px;}
 
-form {padding-right:20px; margin: 1em 0; }
-
-form fieldset {
-  clear: both;
-  font-size: 100%;
-  border-color: #000000;
-  border-width: 1px 0 0 0;
-  border-style: solid none none none;
-  padding: 10px;
-  margin: 0 0 0 0;
-}
-
-form fieldset legend {
-  font-size: 150%;
-  font-weight: bold;
-  color: #000000;
-  margin: 0 0 0 0;
-  padding: 0 5px;
-}
-
-label {
-  font-size: 12px;
-}
-td, th
-{
-vertical-align:middle;
-}
-
 .infotip
 {
 width:300px;
@@ -289,3 +276,6 @@ color:red;
 
 .horizontal-radio-buttons ul { margin-left: 0 }
 .horizontal-radio-buttons li { display: inline }
+
+.delete-row { position: absolute; top: 10px; right: 10px }
+.add-row { float: right; margin-right: 21px }
diff --git a/auf_savoirs_en_partage/media/js/chercheur_edit.js b/auf_savoirs_en_partage/media/js/chercheur_edit.js
new file mode 100644 (file)
index 0000000..f583ee6
--- /dev/null
@@ -0,0 +1,8 @@
+$(document).ready(function() {
+    $('#expertises fieldset').formset({
+        prefix: 'expertise',
+        addText: 'ajouter une expertise',
+        deleteText: 'supprimer cette expertise',
+        formCssClass: 'dynamic-form-expertises'
+    });
+});
diff --git a/auf_savoirs_en_partage/media/js/jquery.formset.js b/auf_savoirs_en_partage/media/js/jquery.formset.js
new file mode 100644 (file)
index 0000000..3f7a280
--- /dev/null
@@ -0,0 +1,170 @@
+/**\r
+ * jQuery Formset 1.1\r
+ * @author Stanislaus Madueke (stan DOT madueke AT gmail DOT com)\r
+ * @requires jQuery 1.2.6 or later\r
+ *\r
+ * Copyright (c) 2009, Stanislaus Madueke\r
+ * All rights reserved.\r
+ *\r
+ * Licensed under the New BSD License\r
+ * See: http://www.opensource.org/licenses/bsd-license.php\r
+ */\r
+;(function($) {\r
+    $.fn.formset = function(opts)\r
+    {\r
+        var options = $.extend({}, $.fn.formset.defaults, opts),\r
+            flatExtraClasses = options.extraClasses.join(' '),\r
+            $$ = $(this),\r
+\r
+            applyExtraClasses = function(row, ndx) {\r
+                if (options.extraClasses) {\r
+                    row.removeClass(flatExtraClasses);\r
+                    row.addClass(options.extraClasses[ndx % options.extraClasses.length]);\r
+                }\r
+            },\r
+\r
+            updateElementIndex = function(elem, prefix, ndx) {\r
+                var idRegex = new RegExp('(' + prefix + '-\\d+-)|(^)'),\r
+                    replacement = prefix + '-' + ndx + '-';\r
+                if (elem.attr("for")) elem.attr("for", elem.attr("for").replace(idRegex, replacement));\r
+                if (elem.attr('id')) elem.attr('id', elem.attr('id').replace(idRegex, replacement));\r
+                if (elem.attr('name')) elem.attr('name', elem.attr('name').replace(idRegex, replacement));\r
+            },\r
+\r
+            hasChildElements = function(row) {\r
+                return row.find('input,select,textarea,label').length > 0;\r
+            },\r
+\r
+            insertDeleteLink = function(row) {\r
+                if (row.is('TR')) {\r
+                    // If the forms are laid out in table rows, insert\r
+                    // the remove button into the last table cell:\r
+                    row.children(':last').append('<a class="' + options.deleteCssClass +'" href="javascript:void(0)">' + options.deleteText + '</a>');\r
+                } else if (row.is('UL') || row.is('OL')) {\r
+                    // If they're laid out as an ordered/unordered list,\r
+                    // insert an <li> after the last list item:\r
+                    row.append('<li><a class="' + options.deleteCssClass + '" href="javascript:void(0)">' + options.deleteText +'</a></li>');\r
+                } else {\r
+                    // Otherwise, just insert the remove button as the\r
+                    // last child element of the form's container:\r
+                    row.append('<a class="' + options.deleteCssClass + '" href="javascript:void(0)">' + options.deleteText +'</a>');\r
+                }\r
+                row.find('a.' + options.deleteCssClass).click(function() {\r
+                    var row = $(this).parents('.' + options.formCssClass),\r
+                        del = row.find('input:hidden[id $= "-DELETE"]');\r
+                    if (del.length) {\r
+                        // We're dealing with an inline formset; rather than remove\r
+                        // this form from the DOM, we'll mark it as deleted and hide\r
+                        // it, then let Django handle the deleting:\r
+                        del.val('on');\r
+                        row.hide();\r
+                    } else {\r
+                        row.remove();\r
+                        // Update the TOTAL_FORMS form count.\r
+                        // Also update names and IDs for all remaining form controls so they remain in sequence:\r
+                        var forms = $('.' + options.formCssClass).not('.formset-custom-template');\r
+                        $('#id_' + options.prefix + '-TOTAL_FORMS').val(forms.length);\r
+                        for (var i=0, formCount=forms.length; i<formCount; i++) {\r
+                            applyExtraClasses(forms.eq(i), i);\r
+                            forms.eq(i).find('input,select,textarea,label').each(function() {\r
+                                updateElementIndex($(this), options.prefix, i);\r
+                            });\r
+                        }\r
+                    }\r
+                    // If a post-delete callback was provided, call it with the deleted form:\r
+                    if (options.removed) options.removed(row);\r
+                    return false;\r
+                });\r
+            };\r
+\r
+        $$.each(function(i) {\r
+            var row = $(this),\r
+                del = row.find('input:checkbox[id $= "-DELETE"]');\r
+            if (del.length) {\r
+                // If you specify "can_delete = True" when creating an inline formset,\r
+                // Django adds a checkbox to each form in the formset.\r
+                // Replace the default checkbox with a hidden field:\r
+                del.before('<input type="hidden" name="' + del.attr('name') +'" id="' + del.attr('id') +'" />');\r
+                del.remove();\r
+            }\r
+            if (hasChildElements(row)) {\r
+                insertDeleteLink(row);\r
+                row.addClass(options.formCssClass);\r
+                applyExtraClasses(row, i);\r
+            }\r
+        });\r
+\r
+        if ($$.length) {\r
+            var addButton, template;\r
+            if (options.formTemplate) {\r
+                // If a form template was specified, we'll clone it to generate new form instances:\r
+                template = (options.formTemplate instanceof $) ? options.formTemplate : $(options.formTemplate);\r
+                template.removeAttr('id').addClass(options.formCssClass).addClass('formset-custom-template');\r
+                template.find('input,select,textarea,label').each(function() {\r
+                    updateElementIndex($(this), options.prefix, 2012);\r
+                });\r
+                insertDeleteLink(template);\r
+            } else {\r
+                // Otherwise, use the last form in the formset; this works much better if you've got\r
+                // extra (>= 1) forms (thnaks to justhamade for pointing this out):\r
+                template = $('.' + options.formCssClass + ':last').clone(true).removeAttr('id');\r
+                template.find('input:hidden[id $= "-DELETE"]').remove();\r
+                template.find('input,select,textarea,label').each(function() {\r
+                    var elem = $(this);\r
+                    // If this is a checkbox or radiobutton, uncheck it.\r
+                    // This fixes Issue 1, reported by Wilson.Andrew.J:\r
+                    if (elem.is('input:checkbox') || elem.is('input:radio')) {\r
+                        elem.attr('checked', false);\r
+                    } else {\r
+                        elem.val('');\r
+                    }\r
+                });\r
+            }\r
+            // FIXME: Perhaps using $.data would be a better idea?\r
+            options.formTemplate = template;\r
+\r
+            if ($$.attr('tagName') == 'TR') {\r
+                // If forms are laid out as table rows, insert the\r
+                // "add" button in a new table row:\r
+                var numCols = $$.eq(0).children().length;\r
+                $$.parent().append('<tr><td colspan="' + numCols + '"><a class="' + options.addCssClass + '" href="javascript:void(0)">' + options.addText + '</a></tr>');\r
+                addButton = $$.parent().find('tr:last a');\r
+                addButton.parents('tr').addClass(options.formCssClass + '-add');\r
+            } else {\r
+                // Otherwise, insert it immediately after the last form:\r
+                $$.filter(':last').after('<a class="' + options.addCssClass + '" href="javascript:void(0)">' + options.addText + '</a>');\r
+                addButton = $$.filter(':last').next();\r
+            }\r
+            addButton.click(function() {\r
+                var formCount = parseInt($('#id_' + options.prefix + '-TOTAL_FORMS').val()),\r
+                    row = options.formTemplate.clone(true).removeClass('formset-custom-template'),\r
+                    buttonRow = $(this).parents('tr.' + options.formCssClass + '-add').get(0) || this;\r
+                applyExtraClasses(row, formCount);\r
+                row.insertBefore($(buttonRow)).show();\r
+                row.find('input,select,textarea,label').each(function() {\r
+                    updateElementIndex($(this), options.prefix, formCount);\r
+                });\r
+                $('#id_' + options.prefix + '-TOTAL_FORMS').val(formCount + 1);\r
+                // If a post-add callback was supplied, call it with the added form:\r
+                if (options.added) options.added(row);\r
+                return false;\r
+            });\r
+        }\r
+\r
+        return $$;\r
+    }\r
+\r
+    /* Setup plugin defaults */\r
+    $.fn.formset.defaults = {\r
+        prefix: 'form',                  // The form prefix for your django formset\r
+        formTemplate: null,              // The jQuery selection cloned to generate new form instances\r
+        addText: 'add another',          // Text for the add link\r
+        deleteText: 'remove',            // Text for the delete link\r
+        addCssClass: 'add-row',          // CSS class applied to the add link\r
+        deleteCssClass: 'delete-row',    // CSS class applied to the delete link\r
+        formCssClass: 'dynamic-form',    // CSS class applied to each form in a formset\r
+        extraClasses: [],                // Additional CSS classes, which will be applied to each form in turn\r
+        added: null,                     // Function called each time a new form is added\r
+        removed: null                    // Function called each time a form is deleted\r
+    };\r
+})(jQuery)\r
diff --git a/auf_savoirs_en_partage/sql/2010-11-09a.sql b/auf_savoirs_en_partage/sql/2010-11-09a.sql
new file mode 100644 (file)
index 0000000..2e4ce3d
--- /dev/null
@@ -0,0 +1,9 @@
+-- Un chercheur a plusieurs expertises et non le contraire
+
+ALTER TABLE chercheurs_expertise ADD COLUMN `chercheur_id` integer NOT NULL AFTER id;
+
+UPDATE chercheurs_expertise e 
+INNER JOIN chercheurs_chercheur c ON c.expertise = e.id
+SET e.chercheur_id = c.id;
+
+ALTER TABLE chercheurs_chercheur DROP COLUMN expertise;
index 09210d7..50f458d 100644 (file)
@@ -3,75 +3,83 @@
 {% if forms.has_errors %}
 <span class="message">Votre fiche n'a pas été enregistrée. Veuillez remplir tous les champs obligatoires (*).</span>
 {% endif %}   
-    <fieldset class="horizontal-radio-buttons">
-        <legend>Informations personnelles</legend>
-        {% with forms.personne as form %}
-            {% include "table_form.html" %}
-        {% endwith %}
-    </fieldset>
+<fieldset class="horizontal-radio-buttons">
+    <legend>Informations personnelles</legend>
+    {% with forms.personne as form %}
+    {% include "table_form.html" %}
+    {% endwith %}
+</fieldset>
 
-    <fieldset>
-        <legend>Informations académiques</legend>
-        <table>
-            {% form_field forms.chercheur.statut %}
-            {% form_field forms.chercheur.diplome %}
-            {% form_field forms.groupes.groupes %}
-        </table>
-    </fieldset>
+<fieldset>
+    <legend>Informations académiques</legend>
+    <table>
+        {% form_field forms.chercheur.statut %}
+        {% form_field forms.chercheur.diplome %}
+        {% form_field forms.groupes.groupes %}
+    </table>
+</fieldset>
 
+<fieldset>
+    <legend>Etablissement de rattachement <span style="color:red">*</span></legend>
+    <table>
+        {% form_field forms.chercheur.etablissement %}
+    </table>
+    <p>Si l'établissement n'existe pas ci-dessus</p>
+    <table>
+        {% form_field forms.chercheur.etablissement_autre_nom %}
+        {% form_field forms.chercheur.etablissement_autre_pays %}
+    </table>
+</fieldset>
+
+<fieldset>
+    <legend>Discipline, thèmes de recherche</legend>
+    <table>
+        {% form_field forms.chercheur.discipline %}
+        {% form_field forms.chercheur.theme_recherche %}
+        {% form_field forms.chercheur.groupe_recherche %}
+        {% form_field forms.chercheur.mots_cles %}
+        {% form_field forms.chercheur.url_site_web %}
+        {% form_field forms.chercheur.url_blog %}
+        {% form_field forms.chercheur.url_reseau_social %}
+    </table>
+</fieldset>
+
+<fieldset>
+    <legend>Activités en Francophonie</legend>
+    <table class="horizontal-radio-buttons">
+        {% form_field forms.chercheur.membre_instance_auf %}
+        {% form_field forms.chercheur.membre_instance_auf_dates %}
+        {% form_field forms.chercheur.expert_oif %}
+        {% form_field forms.chercheur.membre_fipf %}
+        {% form_field forms.chercheur.membre_fipf_association %}
+    </table>
+</fieldset>
+
+<fieldset id="expertises" class="horizontal-radio-buttons">
+    <legend>Expertises</legend>
+    {{ forms.expertises.management_form }}
+    {% for form in forms.expertises.forms %}
     <fieldset>
-        <legend>Etablissement de rattachement <span style="color:red">*</span></legend>
-        <table>
-            {% form_field forms.chercheur.etablissement %}
-        </table>
-        <p>Si l'établissement n'existe pas ci-dessus</p>
-        <table>
-            {% form_field forms.chercheur.etablissement_autre_nom %}
-            {% form_field forms.chercheur.etablissement_autre_pays %}
-        </table>
-    </fieldset>
-    
-    <fieldset>
-        <legend>Discipline, thèmes de recherche</legend>
         <table>
-            {% form_field forms.chercheur.discipline %}
-            {% form_field forms.chercheur.theme_recherche %}
-            {% form_field forms.chercheur.groupe_recherche %}
-            {% form_field forms.chercheur.mots_cles %}
-            {% form_field forms.chercheur.url_site_web %}
-            {% form_field forms.chercheur.url_blog %}
-            {% form_field forms.chercheur.url_reseau_social %}
-        </table>
-    </fieldset>
-    
-    <fieldset>
-        <legend>Activités en Francophonie</legend>
-        <table class="horizontal-radio-buttons">
-            {% form_field forms.chercheur.membre_instance_auf %}
-            {% form_field forms.chercheur.membre_instance_auf_dates %}
-            {% form_field forms.chercheur.expert_oif %}
-            {% form_field forms.chercheur.membre_fipf %}
-            {% form_field forms.chercheur.membre_fipf_association %}
+            {% form_field form.nom %}
+            {% form_field form.date %}
+            {% form_field form.organisme_demandeur %}
+            {% form_field form.organisme_demandeur_visible %}
         </table>
+        {{ form.id }}
+        {{ form.DELETE }}
     </fieldset>
+    {% endfor %}
+</fieldset>
 
-    <fieldset class="horizontal-radio-buttons">
-        <legend>Expertise</legend>
-        <div>
-            {% with forms.expertise as form %}
-                {% include "table_form.html" %}
+<fieldset>
+    <legend>Thèse ou mémoire</legend>
+    <div>
+        <div class="publication">
+            {% with forms.these as form %}
+            {% include "table_form.html" %}
             {% endwith %}
         </div>
-    </fieldset>
-
-    <fieldset>
-        <legend>Thèse ou mémoire</legend>
-        <div>
-            <div class="publication">
-              {% with forms.these as form %}
-                  {% include "table_form.html" %}
-              {% endwith %}
-            </div>
-            <div style="clear:both"></div>
-        </div>
-    </fieldset>
+        <div style="clear:both"></div>
+    </div>
+</fieldset>
index 03cc4a6..1fbf121 100644 (file)
@@ -1,5 +1,10 @@
 {% extends "container_base.html" %}
 
+{% block extra-script %}
+<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery.formset.js"></script>
+<script type="text/javascript" src="{{ MEDIA_URL }}js/chercheur_edit.js"></script>
+{% endblock %}
+
 {% block contenu %}
 <h4>{{chercheur.personne.prenom}} {{chercheur.personne.nom}}</h4>
 <div class="contenu-wrapper">
index cec62fe..f4cdd3e 100644 (file)
     </table>
     {% endif %}
 
-    {% if chercheur.expertise %}
-    <h5>Expertise</h5>
+    {% if chercheur.expertises.all %}
+    <h5>Expertises</h5>
+    {% for expertise in chercheur.expertises.all %}
     <table>
         <tr>
             <td class="label">Titre de l'expertise:</td>
-            <td>{{ chercheur.expertise.nom }}</td>
+            <td>{{ expertise.nom }}</td>
         </tr>
-        {% if chercheur.expertise.date %}
+        {% if expertise.date %}
         <tr>
             <td class="label">Date:</td>
-            <td>{{ chercheur.expertise.date }}</td>
+            <td>{{ expertise.date }}</td>
         </tr>
         {% endif %}
-        {% if chercheur.expertise.organisme_demandeur and chercheur.expertise.organisme_demandeur_visible %}
+        {% if expertise.organisme_demandeur and expertise.organisme_demandeur_visible %}
         <tr>
             <td class="label">Organisme demandeur:</td>
-            <td>{{ chercheur.expertise.organisme_demandeur }}</td>
+            <td>{{ expertise.organisme_demandeur }}</td>
         </tr>
         {% endif %}
     </table>
+    {% if not forloop.last %}
+    <hr>
+    {% endif %}
+    {% endfor %}
     {% endif %}
 
     <h5>Publications</h5>
index 464f857..8c47554 100644 (file)
@@ -1,5 +1,10 @@
 {% extends "container_base.html" %}
 
+{% block extra-script %}
+<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery.formset.js"></script>
+<script type="text/javascript" src="{{ MEDIA_URL }}js/chercheur_edit.js"></script>
+{% endblock %}
+
 {% block contenu %}
 <h4>Inscription au répertoire de chercheurs</h4>