Reorder taggedsheet by drag and drop. Remove wikipedia_activated for a tag. TagCategory chosen by closed list.
authorcavaliet
Fri, 17 Jun 2011 17:14:09 +0200
changeset 44 244d805b4921
parent 43 e0812bc3ef44
child 45 297f7960754c
Reorder taggedsheet by drag and drop. Remove wikipedia_activated for a tag. TagCategory chosen by closed list.
web/hdabo/models.py
web/hdabo/static/hdabo/css/style.css
web/hdabo/static/hdabo/img/arrow_down.png
web/hdabo/static/hdabo/img/arrow_up.png
web/hdabo/static/hdabo/img/arrow_up_down.png
web/hdabo/static/hdabo/js/hdabo.js
web/hdabo/templates/all_tags.html
web/hdabo/templates/list_for_orga.html
web/hdabo/templates/partial/all_tags_table.html
web/hdabo/templates/partial/tag_table.html
web/hdabo/urls.py
web/hdabo/views.py
--- a/web/hdabo/models.py	Fri Jun 17 14:17:49 2011 +0200
+++ b/web/hdabo/models.py	Fri Jun 17 17:14:09 2011 +0200
@@ -1,278 +1,278 @@
-# -*- coding: utf-8 -*-
-
-from django.contrib.auth.models import User
-from django.db import models
-from hdabo.fields import SortedManyToManyField
-from hdabo.utils import Property
-import datetime
-
-class Organisation(models.Model):
-    hda_id = models.CharField(max_length=512, unique=True, blank=False, null=False)
-    name = models.CharField(max_length=512, unique=False, blank=False, null=False)
-    location = models.CharField(max_length=512, unique=False, blank=True, null=True)
-    website = models.CharField(max_length=2048, unique=False, blank=True, null=True)
-    
-
-class Author(models.Model):
-    hda_id = models.CharField(max_length=512, unique=True, blank=False, null=False)
-    lastname = models.CharField(max_length=512, unique=False, blank=True, null=True)
-    firstname = models.CharField(max_length=512, unique=False, blank=True, null=True)
-
-class TimePeriod(models.Model):
-    TIME_PERIOD_CHOICES = (
-        (1, u'Primaire'),
-        (2, u'Collège'),
-        (3, u'Lycée'),
-    )
-    TIME_PERIOD_DICT = {
-        u'Primaire': 1,
-        u'Collège': 2,
-        u'Lycée': 3,
-    }
-    label = models.CharField(max_length=512, unique=False, blank=False, null=False)
-    school_period = models.IntegerField(choices=TIME_PERIOD_CHOICES)
-    
-    class Meta:
-        unique_together = ("label", "school_period")
-
-    def __unicode__(self):
-        return unicode(self.label)
-
-
-class Domain(models.Model):
-    DOMAIN_PERIOD_CHOICES = (
-        (0, u'Global'),
-        (1, u'Primaire'),
-        (2, u'Collège'),
-        (3, u'Lycée'),
-    )
-    DOMAIN_PERIOD_DICT = {
-        u'Global': 0,
-        u'Primaire': 1,
-        u'Collège': 2,
-        u'Lycée': 3,
-    }
-    label = models.CharField(max_length=512, unique=False, blank=False, null=False)
-    school_period = models.IntegerField(choices=DOMAIN_PERIOD_CHOICES)
-
-    class Meta:
-        unique_together = ("label", "school_period")
-
-    def __unicode__(self):
-        return unicode(self.label)
-
-
-class DocumentFormat(models.Model):
-    label = models.CharField(max_length=512, unique=True, blank=False, null=False)
-
-    def __unicode__(self):
-        return unicode(self.label)
-    
-class TagCategory(models.Model):
-    label = models.CharField(max_length=512, unique=True, blank=False, null=False)
-    
-    def __unicode__(self):
-        return unicode(self.label)
-    
-    class Meta:
-        verbose_name_plural = "TagCategories"
-
-class Tag(models.Model):
-    TAG_URL_STATUS_CHOICES = (
-        (0, "null_result"),
-        (1, "redirection"),
-        (2, "homonyme"),
-        (3, "match"),
-    )
-    
-    TAG_URL_STATUS_DICT = {
-        "null_result":0,
-        "redirection":1,
-        "homonyme":2,
-        "match":3,
-    }
-    
-    label = models.CharField(max_length=1024, unique=False, blank=False, null=False)
-    original_label = models.CharField(max_length=1024, unique=True, blank=False, null=False, editable=False)
-    alias = models.CharField(max_length=1024, unique=False, blank=True, null=True)
-    category = models.ForeignKey(TagCategory, null=True, blank=True)
-    wikipedia_url = models.URLField(verify_exists=False, max_length=2048, blank=True, null=True)
-    wikipedia_pageid = models.BigIntegerField(unique=False, blank=True, null=True)
-    url_status = models.IntegerField(choices=TAG_URL_STATUS_CHOICES, blank=True, null=True, default=None)
-    dbpedia_uri = models.URLField(verify_exists=False, max_length=2048, blank=True, null=True)
-
-    @Property
-    def url_status_text(): #@NoSelf
-        def fget(self):
-            return self.TAG_URL_STATUS_CHOICES[self.url_status][1]
-        
-        return locals() 
-        
-class Location(models.Model):
-    name = models.CharField(max_length=512, unique=False, blank=False, null=False)
-    insee = models.CharField(max_length=5, unique=True, blank=False, null=False)
-
-    def __unicode__(self):
-        return unicode("%s : %s" % (self.name, self.insee))
-
-class Datasheet(models.Model):
-    hda_id = models.CharField(max_length=512, unique=True, blank=False, null=False)
-    author = models.ForeignKey(Author, null=True, blank=True)
-    organisation = models.ForeignKey(Organisation)
-    title = models.CharField(max_length=2048, unique=False, blank=False, null=False)
-    description = models.TextField(blank=True, null=True)
-    url = models.URLField(verify_exists=False, max_length=2048, blank=True, null=True)
-    domains = SortedManyToManyField(Domain, limit_choices_to={'school_period':Domain.DOMAIN_PERIOD_DICT[u'Global']}, related_name="datasheets")
-    primary_periods = SortedManyToManyField(TimePeriod, limit_choices_to={'school_period':TimePeriod.TIME_PERIOD_DICT[u'Primaire']}, related_name="primary_periods_datasheets")
-    college_periods = SortedManyToManyField(TimePeriod, limit_choices_to={'school_period':TimePeriod.TIME_PERIOD_DICT[u'Collège']}, related_name="college_periods_datasheets")
-    highschool_periods = SortedManyToManyField(TimePeriod, limit_choices_to={'school_period':TimePeriod.TIME_PERIOD_DICT[u'Lycée']}, related_name="highschool_periods_datasheets")
-    primary_themes = SortedManyToManyField(Domain, limit_choices_to={'school_period':Domain.DOMAIN_PERIOD_DICT[u'Primaire']}, related_name="primary_themes_datasheets")
-    college_themes = SortedManyToManyField(Domain, limit_choices_to={'school_period':Domain.DOMAIN_PERIOD_DICT[u'Collège']}, related_name="college_themes_datasheets")
-    highschool_themes = SortedManyToManyField(Domain, limit_choices_to={'school_period':Domain.DOMAIN_PERIOD_DICT[u'Lycée']}, related_name="highschool_themes_datasheets")
-    town = models.ForeignKey(Location, null=True, blank=True)
-    format = models.ForeignKey(DocumentFormat, null=True, blank=True)
-    original_creation_date = models.DateField()
-    original_modification_date = models.DateField()
-    modification_datetime = models.DateTimeField(auto_now=True)
-    validation_date = models.DateTimeField(null=True, blank=True)
-    validated = models.BooleanField(default=False)
-    validator = models.ForeignKey(User, null=True, blank=True)
-    tags = models.ManyToManyField(Tag, through='TaggedSheet')
-    
-    
-    def validate(self, user):
-        self.validation_date = datetime.datetime.now()
-        self.validated = True
-        self.validator = user
-        self.save()
-    
-    def unvalidate(self):
-        self.validation_date = datetime.datetime.min
-        self.validated = False
-        self.validator = None
-        self.save()
-
-    @Property
-    def domains_list(): #@NoSelf
-        def fget(self):
-            return [d.label for d in self.domains.all()]
-        
-        return locals() 
-
-    @Property
-    def domains_text(): #@NoSelf
-        def fget(self):
-            return "; ".join(self.domains_list)
-        
-        return locals() 
-
-    @Property
-    def primary_periods_list(): #@NoSelf
-        def fget(self):
-            return [d.label for d in self.primary_periods.all()] 
-
-        return locals() 
-
-    
-    @Property
-    def primary_periods_text(): #@NoSelf
-        def fget(self):
-            return "; ".join(self.primary_periods_list) 
-
-        return locals() 
-
-    @Property
-    def college_periods_list(): #@NoSelf
-        def fget(self):
-            return [d.label for d in self.college_periods.all()] 
-
-        return locals() 
-
-    @Property
-    def college_periods_text(): #@NoSelf
-        def fget(self):
-            return "; ".join(self.college_periods_list) 
-
-        return locals() 
-
-    @Property
-    def highschool_periods_list(): #@NoSelf
-        def fget(self):
-            return [d.label for d in self.highschool_periods.all()] 
-
-        return locals() 
-
-    @Property
-    def highschool_periods_text(): #@NoSelf
-        def fget(self):
-            return "; ".join(self.highschool_periods_list) 
-
-        return locals() 
-
-
-    @Property
-    def primary_themes_list(): #@NoSelf
-        def fget(self):
-            return [d.label for d in self.primary_themes.all()] 
-
-        return locals() 
-
-
-    @Property
-    def primary_themes_text(): #@NoSelf
-        def fget(self):
-            return "; ".join(self.primary_themes_list) 
-
-        return locals() 
-
-    @Property
-    def college_themes_list(): #@NoSelf
-        def fget(self):
-            return [d.label for d in self.college_themes.all()] 
-
-        return locals() 
-    
-    @Property
-    def college_themes_text(): #@NoSelf
-        def fget(self):
-            return "; ".join(self.college_themes_list) 
-
-        return locals() 
-
-    @Property
-    def highschool_themes_list(): #@NoSelf
-        def fget(self):
-            return [d.label for d in self.highschool_themes.all()] 
-
-        return locals()
-
-    @Property
-    def highschool_themes_text(): #@NoSelf
-        def fget(self):
-            return "; ".join(self.highschool_themes_list) 
-
-        return locals()
-
-    @Property
-    def town_text(): #@NoSelf
-        def fget(self):
-            return self.town.name if self.town else ""
-        
-        return locals()
-
-    @Property
-    def tags_text(): #@NoSelf
-        def fget(self):
-            return "; ".join([t.label for t in self.tags.all()])
-        
-        return locals()
-
-
-class TaggedSheet(models.Model):
-    datasheet = models.ForeignKey(Datasheet)
-    tag = models.ForeignKey(Tag)
-    original_order = models.IntegerField(default=0)
-    order = models.IntegerField(default=0)
-    index_note = models.FloatField(default=0.0)    
-    
-    
+# -*- coding: utf-8 -*-
+
+from django.contrib.auth.models import User
+from django.db import models
+from hdabo.fields import SortedManyToManyField
+from hdabo.utils import Property
+import datetime
+
+class Organisation(models.Model):
+    hda_id = models.CharField(max_length=512, unique=True, blank=False, null=False)
+    name = models.CharField(max_length=512, unique=False, blank=False, null=False)
+    location = models.CharField(max_length=512, unique=False, blank=True, null=True)
+    website = models.CharField(max_length=2048, unique=False, blank=True, null=True)
+    
+
+class Author(models.Model):
+    hda_id = models.CharField(max_length=512, unique=True, blank=False, null=False)
+    lastname = models.CharField(max_length=512, unique=False, blank=True, null=True)
+    firstname = models.CharField(max_length=512, unique=False, blank=True, null=True)
+
+class TimePeriod(models.Model):
+    TIME_PERIOD_CHOICES = (
+        (1, u'Primaire'),
+        (2, u'Collège'),
+        (3, u'Lycée'),
+    )
+    TIME_PERIOD_DICT = {
+        u'Primaire': 1,
+        u'Collège': 2,
+        u'Lycée': 3,
+    }
+    label = models.CharField(max_length=512, unique=False, blank=False, null=False)
+    school_period = models.IntegerField(choices=TIME_PERIOD_CHOICES)
+    
+    class Meta:
+        unique_together = ("label", "school_period")
+
+    def __unicode__(self):
+        return unicode(self.label)
+
+
+class Domain(models.Model):
+    DOMAIN_PERIOD_CHOICES = (
+        (0, u'Global'),
+        (1, u'Primaire'),
+        (2, u'Collège'),
+        (3, u'Lycée'),
+    )
+    DOMAIN_PERIOD_DICT = {
+        u'Global': 0,
+        u'Primaire': 1,
+        u'Collège': 2,
+        u'Lycée': 3,
+    }
+    label = models.CharField(max_length=512, unique=False, blank=False, null=False)
+    school_period = models.IntegerField(choices=DOMAIN_PERIOD_CHOICES)
+
+    class Meta:
+        unique_together = ("label", "school_period")
+
+    def __unicode__(self):
+        return unicode(self.label)
+
+
+class DocumentFormat(models.Model):
+    label = models.CharField(max_length=512, unique=True, blank=False, null=False)
+
+    def __unicode__(self):
+        return unicode(self.label)
+    
+class TagCategory(models.Model):
+    label = models.CharField(max_length=512, unique=True, blank=False, null=False)
+    
+    def __unicode__(self):
+        return unicode(self.label)
+    
+    class Meta:
+        verbose_name_plural = "TagCategories"
+
+class Tag(models.Model):
+    TAG_URL_STATUS_CHOICES = (
+        (0, "null_result"),
+        (1, "redirection"),
+        (2, "homonyme"),
+        (3, "match"),
+    )
+    
+    TAG_URL_STATUS_DICT = {
+        "null_result":0,
+        "redirection":1,
+        "homonyme":2,
+        "match":3,
+    }
+    
+    label = models.CharField(max_length=1024, unique=False, blank=False, null=False)
+    original_label = models.CharField(max_length=1024, unique=True, blank=False, null=False, editable=False)
+    alias = models.CharField(max_length=1024, unique=False, blank=True, null=True)
+    category = models.ForeignKey(TagCategory, null=True, blank=True)
+    wikipedia_url = models.URLField(verify_exists=False, max_length=2048, blank=True, null=True)
+    wikipedia_pageid = models.BigIntegerField(unique=False, blank=True, null=True)
+    url_status = models.IntegerField(choices=TAG_URL_STATUS_CHOICES, blank=True, null=True, default=None)
+    dbpedia_uri = models.URLField(verify_exists=False, max_length=2048, blank=True, null=True)
+
+    @Property
+    def url_status_text(): #@NoSelf
+        def fget(self):
+            return self.TAG_URL_STATUS_CHOICES[self.url_status][1]
+        
+        return locals() 
+        
+class Location(models.Model):
+    name = models.CharField(max_length=512, unique=False, blank=False, null=False)
+    insee = models.CharField(max_length=5, unique=True, blank=False, null=False)
+
+    def __unicode__(self):
+        return unicode("%s : %s" % (self.name, self.insee))
+
+class Datasheet(models.Model):
+    hda_id = models.CharField(max_length=512, unique=True, blank=False, null=False)
+    author = models.ForeignKey(Author, null=True, blank=True)
+    organisation = models.ForeignKey(Organisation)
+    title = models.CharField(max_length=2048, unique=False, blank=False, null=False)
+    description = models.TextField(blank=True, null=True)
+    url = models.URLField(verify_exists=False, max_length=2048, blank=True, null=True)
+    domains = SortedManyToManyField(Domain, limit_choices_to={'school_period':Domain.DOMAIN_PERIOD_DICT[u'Global']}, related_name="datasheets")
+    primary_periods = SortedManyToManyField(TimePeriod, limit_choices_to={'school_period':TimePeriod.TIME_PERIOD_DICT[u'Primaire']}, related_name="primary_periods_datasheets")
+    college_periods = SortedManyToManyField(TimePeriod, limit_choices_to={'school_period':TimePeriod.TIME_PERIOD_DICT[u'Collège']}, related_name="college_periods_datasheets")
+    highschool_periods = SortedManyToManyField(TimePeriod, limit_choices_to={'school_period':TimePeriod.TIME_PERIOD_DICT[u'Lycée']}, related_name="highschool_periods_datasheets")
+    primary_themes = SortedManyToManyField(Domain, limit_choices_to={'school_period':Domain.DOMAIN_PERIOD_DICT[u'Primaire']}, related_name="primary_themes_datasheets")
+    college_themes = SortedManyToManyField(Domain, limit_choices_to={'school_period':Domain.DOMAIN_PERIOD_DICT[u'Collège']}, related_name="college_themes_datasheets")
+    highschool_themes = SortedManyToManyField(Domain, limit_choices_to={'school_period':Domain.DOMAIN_PERIOD_DICT[u'Lycée']}, related_name="highschool_themes_datasheets")
+    town = models.ForeignKey(Location, null=True, blank=True)
+    format = models.ForeignKey(DocumentFormat, null=True, blank=True)
+    original_creation_date = models.DateField()
+    original_modification_date = models.DateField()
+    modification_datetime = models.DateTimeField(auto_now=True)
+    validation_date = models.DateTimeField(null=True, blank=True)
+    validated = models.BooleanField(default=False)
+    validator = models.ForeignKey(User, null=True, blank=True)
+    tags = models.ManyToManyField(Tag, through='TaggedSheet')
+    
+    
+    def validate(self, user):
+        self.validation_date = datetime.datetime.now()
+        self.validated = True
+        self.validator = user
+        self.save()
+    
+    def unvalidate(self):
+        self.validation_date = datetime.datetime.min
+        self.validated = False
+        self.validator = None
+        self.save()
+
+    @Property
+    def domains_list(): #@NoSelf
+        def fget(self):
+            return [d.label for d in self.domains.all()]
+        
+        return locals() 
+
+    @Property
+    def domains_text(): #@NoSelf
+        def fget(self):
+            return "; ".join(self.domains_list)
+        
+        return locals() 
+
+    @Property
+    def primary_periods_list(): #@NoSelf
+        def fget(self):
+            return [d.label for d in self.primary_periods.all()] 
+
+        return locals() 
+
+    
+    @Property
+    def primary_periods_text(): #@NoSelf
+        def fget(self):
+            return "; ".join(self.primary_periods_list) 
+
+        return locals() 
+
+    @Property
+    def college_periods_list(): #@NoSelf
+        def fget(self):
+            return [d.label for d in self.college_periods.all()] 
+
+        return locals() 
+
+    @Property
+    def college_periods_text(): #@NoSelf
+        def fget(self):
+            return "; ".join(self.college_periods_list) 
+
+        return locals() 
+
+    @Property
+    def highschool_periods_list(): #@NoSelf
+        def fget(self):
+            return [d.label for d in self.highschool_periods.all()] 
+
+        return locals() 
+
+    @Property
+    def highschool_periods_text(): #@NoSelf
+        def fget(self):
+            return "; ".join(self.highschool_periods_list) 
+
+        return locals() 
+
+
+    @Property
+    def primary_themes_list(): #@NoSelf
+        def fget(self):
+            return [d.label for d in self.primary_themes.all()] 
+
+        return locals() 
+
+
+    @Property
+    def primary_themes_text(): #@NoSelf
+        def fget(self):
+            return "; ".join(self.primary_themes_list) 
+
+        return locals() 
+
+    @Property
+    def college_themes_list(): #@NoSelf
+        def fget(self):
+            return [d.label for d in self.college_themes.all()] 
+
+        return locals() 
+    
+    @Property
+    def college_themes_text(): #@NoSelf
+        def fget(self):
+            return "; ".join(self.college_themes_list) 
+
+        return locals() 
+
+    @Property
+    def highschool_themes_list(): #@NoSelf
+        def fget(self):
+            return [d.label for d in self.highschool_themes.all()] 
+
+        return locals()
+
+    @Property
+    def highschool_themes_text(): #@NoSelf
+        def fget(self):
+            return "; ".join(self.highschool_themes_list) 
+
+        return locals()
+
+    @Property
+    def town_text(): #@NoSelf
+        def fget(self):
+            return self.town.name if self.town else ""
+        
+        return locals()
+
+    @Property
+    def tags_text(): #@NoSelf
+        def fget(self):
+            return "; ".join([t.label for t in self.tags.all()])
+        
+        return locals()
+
+
+class TaggedSheet(models.Model):
+    datasheet = models.ForeignKey(Datasheet)
+    tag = models.ForeignKey(Tag)
+    original_order = models.IntegerField(default=0)
+    order = models.IntegerField(default=0)
+    index_note = models.FloatField(default=0.0)    
+    
+    
--- a/web/hdabo/static/hdabo/css/style.css	Fri Jun 17 14:17:49 2011 +0200
+++ b/web/hdabo/static/hdabo/css/style.css	Fri Jun 17 17:14:09 2011 +0200
@@ -361,10 +361,26 @@
 .text_centered {
 	text-align: center;
 }
-.hand_cursor, .reset_wp_info, .updown_td, .remove_wp_link, .remove_tag_from_list {
+.hand_cursor, .reset_wp_info, .remove_wp_link, .remove_tag_from_list {
 	cursor: pointer;
 }
+.updown_td {
+	cursor: n-resize;
+}
 
+tr.dragged_row td {
+    color: yellow;
+    background-color: black;
+}
+
+#all_tags_table {
+	min-width: 600px;
+	border-spacing: 0px;
+}
+#all_tags_table td, th {
+	/*border: thin solid #6495ed;*/
+	padding: 3px;
+}
 
 /* styles for the 4 types of STATUS*/
 .null_result {
Binary file web/hdabo/static/hdabo/img/arrow_down.png has changed
Binary file web/hdabo/static/hdabo/img/arrow_up.png has changed
Binary file web/hdabo/static/hdabo/img/arrow_up_down.png has changed
--- a/web/hdabo/static/hdabo/js/hdabo.js	Fri Jun 17 14:17:49 2011 +0200
+++ b/web/hdabo/static/hdabo/js/hdabo.js	Fri Jun 17 17:14:09 2011 +0200
@@ -1,11 +1,6 @@
 // -*- coding: utf-8 -*-
 function init_tags_events()
 {
-    // Up and down management for tag table lines
-    $(".up,.down").click(function(){
-        tag_up_down(this);
-    });
-    
     // Tag simple operations : activate/unactivate wp link, reset wp info, remove wp link, remove tag from list
     $(".reset_wp_info").click(function(e){
         if(confirm("Confirmez-vous le rétablissement du label original de ce tag ?")){
@@ -100,6 +95,57 @@
             init_tags_events();
     	}
     });
+    
+    // Tag categories management
+    $(".tag_category").editable(update_tag_category_url, {
+    	indicator : "<img src='"+static_url+"hdabo/img/indicator.gif'>",
+    	type      : "select",
+        loadurl   : get_categories_url,
+    	placeholder:"",
+    	tooltip   : "Cliquer pour éditer...",
+    	onblur    : "submit",
+    	submitdata: {
+            csrfmiddlewaretoken:global_csrf_token,
+            num_page:$('#num_page').val(),
+            nb_by_page:$('#nb_by_page').val()
+        },
+    	callback  : function(value, settings) {
+            $('#tag_table_container').html(value);
+            init_tags_events();
+    	}
+    });
+    
+    // Tag table drag and drop
+    $("#tag_table").tableDnD({
+        onDragClass: "dragged_row",
+        onDrop: function(table, row){
+            old_order = row.id;
+            $($(row).children()[1]).html("<img src='"+static_url+"hdabo/img/indicator.gif'>");
+            rows = table.tBodies[0].rows;
+            nb_rows = rows.length;
+            for(var i=1; i<nb_rows; i++){
+                if(rows[i].id==old_order){
+                    new_order = i; // No need to +1 because rows[0] are headers
+                    $.ajax({
+                        url: tag_up_down_url,
+                        type: 'POST',
+                        data: {csrfmiddlewaretoken:global_csrf_token, 
+                               datasheet_id:$('#datasheet_id').val(),
+                               new_order:new_order,
+                               old_order:old_order
+                               },
+                        // bug with jquery >= 1.5, "json" adds a callback so we don't specify dataType
+                        //dataType: 'json',
+                        success: function(msg, textStatus, XMLHttpRequest) {
+                            $('#tag_table_container').html(msg);
+                            init_tags_events();
+                        }
+                    });
+                }
+            }
+        },
+        dragHandle: "updown_td"
+    });
 }
 
 function init_datasheet_events()
--- a/web/hdabo/templates/all_tags.html	Fri Jun 17 14:17:49 2011 +0200
+++ b/web/hdabo/templates/all_tags.html	Fri Jun 17 17:14:09 2011 +0200
@@ -5,6 +5,7 @@
     {{block.super}}
     <script type="text/javascript" src="{{STATIC_URL}}hdabo/js/jquery-ui.min.js"></script>
     <script type="text/javascript" src="{{STATIC_URL}}hdabo/js/jquery.jeditable.js"></script>
+    <script type="text/javascript" src="{{STATIC_URL}}hdabo/js/jquery.tablednd_0_5.js"></script>
     {% endblock %}
     
     {% block js_declaration %}
@@ -20,6 +21,8 @@
     var add_tag_url = "{% url hdabo.views.add_tag %}";
     var remove_wp_link_url = "{% url hdabo.views.remove_wp_link %}";
     var update_tag_alias_url = "{% url hdabo.views.update_tag_alias %}";
+    var update_tag_category_url = "{% url hdabo.views.update_tag_category %}";
+    var get_categories_url = "{% url hdabo.views.get_categories %}";
     
     $(document).ready(function(){
         init_tags_events();
--- a/web/hdabo/templates/list_for_orga.html	Fri Jun 17 14:17:49 2011 +0200
+++ b/web/hdabo/templates/list_for_orga.html	Fri Jun 17 17:14:09 2011 +0200
@@ -5,6 +5,7 @@
     {{block.super}}
     <script type="text/javascript" src="{{STATIC_URL}}hdabo/js/jquery-ui.min.js"></script>
     <script type="text/javascript" src="{{STATIC_URL}}hdabo/js/jquery.jeditable.js"></script>
+    <script type="text/javascript" src="{{STATIC_URL}}hdabo/js/jquery.tablednd_0_5.js"></script>
     {% endblock %}
     
     {% block js_declaration %}
@@ -22,6 +23,8 @@
     var remove_wp_link_url = "{% url hdabo.views.remove_wp_link %}";
     var validate_datasheet_url = "{% url hdabo.views.validate_datasheet %}";
     var update_tag_alias_url = "{% url hdabo.views.update_tag_alias %}";
+    var update_tag_category_url = "{% url hdabo.views.update_tag_category %}";
+    var get_categories_url = "{% url hdabo.views.get_categories %}";
     
     $(document).ready(function(){
         init_tags_events();
--- a/web/hdabo/templates/partial/all_tags_table.html	Fri Jun 17 14:17:49 2011 +0200
+++ b/web/hdabo/templates/partial/all_tags_table.html	Fri Jun 17 17:14:09 2011 +0200
@@ -1,33 +1,26 @@
-{% block tag_table %}
-	<table id="all_tags_table">
-    <tr><th>id</th>
-        <th>label</th>
-        {% comment %}<th>original_label</th>{% endcomment %}
-        <th class="text_centered">Lien W</th>
-        <th>Facette</th>
-        <th class="large_25 text_centered">Supprimer<br/>le lien W</th>
-        <th>Alias</th></tr>
-    {% for tag in tags %}
-    <tr class="imageline {% cycle 'hdabooddline' 'hdaboevenline' %}">
-        <td class="reset_wp_info">{{tag.id}}</td>
-        <td class="{{tag.url_status_text}} wikipediatag" id="{{tag.id}}" >{{tag.label}}</td>
-        {% comment %}<td>{{tag.original_label}}</td>{% endcomment %}
-        <td class="text_centered">
-            {% if tag.wikipedia_url and tag.wikipedia_url != ""  %}
-            <a href="{{tag.wikipedia_url}}" target="_blank"><img src="{{STATIC_URL}}hdabo/img/arrow_right.png" ></a>
-            {% else %}
-            <a href="http://fr.wikipedia.org/w/index.php?search={{tag.label}}" target="_blank"><img src="{{STATIC_URL}}hdabo/img/wikipedia_search.png" ></a>
-            {% endif %}</td>
-        <td><select name="facette">
-            <option value="" selected></option>
-            <option value="datation">Datation</option>
-            <option value="localisation">Localisation</option>
-            <option value="createur">Créateur</option>
-            <option value="ecole">Ecole/Mouvement</option>
-            <option value="discipline">Discipline artistique</option>
-            </select></td>
-        <td class="text_centered"><img src="{{STATIC_URL}}hdabo/img/red_cross.png" class="remove_wp_link" id="{{tag.id}}" alt="{{tag.label}}" /></td>
-        <td class="tag_alias" id="{{tag.id}}" >{% if tag.alias %}{{tag.alias}}{% endif %}</td></tr>
-    {% endfor %}
-    </table>
-{% endblock %}
+{% block tag_table %}
+	<table id="all_tags_table">
+    <tr><th>id</th>
+        <th>label</th>
+        {% comment %}<th>original_label</th>{% endcomment %}
+        <th class="text_centered">Lien W</th>
+        <th>Facette</th>
+        <th class="large_25 text_centered">Supprimer<br/>le lien W</th>
+        <th>Alias</th></tr>
+    {% for tag in tags %}
+    <tr class="imageline {% cycle 'hdabooddline' 'hdaboevenline' %}">
+        <td class="reset_wp_info">{{tag.id}}</td>
+        <td class="{{tag.url_status_text}} wikipediatag" id="{{tag.id}}" >{{tag.label}}</td>
+        {% comment %}<td>{{tag.original_label}}</td>{% endcomment %}
+        <td class="text_centered">
+            {% if tag.wikipedia_url and tag.wikipedia_url != ""  %}
+            <a href="{{tag.wikipedia_url}}" target="_blank"><img src="{{STATIC_URL}}hdabo/img/arrow_right.png" ></a>
+            {% else %}
+            <a href="http://fr.wikipedia.org/w/index.php?search={{tag.label}}" target="_blank"><img src="{{STATIC_URL}}hdabo/img/wikipedia_search.png" ></a>
+            {% endif %}</td>
+        <td class="tag_category" id="{{tag.id}}">{% if tag.category %}{{ tag.category }}{% endif %}</td>
+        <td class="text_centered"><img src="{{STATIC_URL}}hdabo/img/red_cross.png" class="remove_wp_link" id="{{tag.id}}" alt="{{tag.label}}" /></td>
+        <td class="tag_alias" id="{{tag.id}}" >{% if tag.alias %}{{tag.alias}}{% endif %}</td></tr>
+    {% endfor %}
+    </table>
+{% endblock %}
--- a/web/hdabo/templates/partial/tag_table.html	Fri Jun 17 14:17:49 2011 +0200
+++ b/web/hdabo/templates/partial/tag_table.html	Fri Jun 17 17:14:09 2011 +0200
@@ -1,74 +1,61 @@
-{% block tag_table %}
-	<table id="tag_table"><tr>
-        <th>#</th>
-        {% if valid != "2" and ordered_tags %}
-        <th class="updown_td">M</th>
-        <th class="updown_td">D</th>
-        {% endif %}
-        <th>id</th>
-        <th>label</th>
-        {% comment %}<th>original_label</th>{% endcomment %}
-        <th class="text_centered">Lien W</th>
-        <th>Facette</th>
-        <th class="large_25 text_centered">Lien W activé</th>
-        <th class="large_25 text_centered">Supprimer<br/>le lien W</th>
-        <th>Alias</th>
-        <th class="large_25 text_centered">Retirer le tag de la liste</th></tr>
-    {% if ordered_tags %}
-    	{# ordered_tags is a list of TaggedSheet #}
-        {% for t in ordered_tags %}
-            <tr class="imageline {% cycle 'hdabooddline' 'hdaboevenline' %}" id="{{t.id}}">
-            <td>{{forloop.counter}}</td>
-            {% if valid != "2" %}
-            <td class="updown_td">{% if not forloop.first %}<img src="{{STATIC_URL}}hdabo/img/arrow_up.png" class="up" alt="up" id="{{t.tag.id}}" pos="{{forloop.counter0}}">{% endif %}</td>
-            <td class="updown_td">{% if not forloop.last %}<img src="{{STATIC_URL}}hdabo/img/arrow_down.png" class="down" alt="down" id="{{t.tag.id}}" pos="{{forloop.counter0}}">{% endif %}</td>
-            {% endif %}
-            <td class="reset_wp_info">{{t.tag.id}}</td>
-            <td class="{{t.tag.url_status_text}} wikipediatag" id="{{t.tag.id}}" >{{t.tag.label}}</td>
-            {% comment %}<td>{{t.tag.original_label}}</td>{% endcomment %}
-            <td class="text_centered">
-	            {% if t.tag.wikipedia_url and t.tag.wikipedia_url != ""  %}
-	            <a href="{{t.tag.wikipedia_url}}" target="_blank"><img src="{{STATIC_URL}}hdabo/img/arrow_right.png" ></a>
-	            {% else %}
-	            <a href="http://fr.wikipedia.org/w/index.php?search={{t.tag.label}}" target="_blank"><img src="{{STATIC_URL}}hdabo/img/wikipedia_search.png" ></a>
-	            {% endif %}</td>
-            <td><select name="facette">
-				<option value="" selected></option>
-				<option value="datation">Datation</option>
-				<option value="localisation">Localisation</option>
-				<option value="createur">Créateur</option>
-				<option value="ecole">Ecole/Mouvement</option>
-				<option value="discipline">Discipline artistique</option>
-				</select></td>
-            <td class="text_centered"><input type="checkbox" class="activate_wp_cb" id="{{t.tag.id}}" alt="{{t.tag.label}}" {% if t.tag.wikipedia_activated %}checked{% endif %} /></td>
-            <td class="text_centered"><img src="{{STATIC_URL}}hdabo/img/red_cross.png" class="remove_wp_link" id="{{t.tag.id}}" alt="{{t.tag.label}}" /></td>
-            <td class="tag_alias" id="{{t.tag.id}}" >{% if t.tag.alias %}{{t.tag.alias}}{% endif %}</td>
-            <td class="text_centered"><img src="{{STATIC_URL}}hdabo/img/tag_remove.png" class="remove_tag_from_list" id="{{t.tag.id}}" alt="{{t.tag.label}}" /></td></tr>
-        {% endfor %}
-    {% else %}
-    	{# ds is a DataSheet #}
-        {% for t in ds.tags.all %}
-            <tr class="imageline {% cycle 'hdabooddline' 'hdaboevenline' %}">
-            <td>{{forloop.counter}}</td>
-            {% if valid != "2" and ordered_tags %}
-            <td class="updown_td">{% if not forloop.first %}<img src="{{STATIC_URL}}hdabo/img/arrow_up.png" class="up" alt="up" id="{{t.id}}" pos="{{forloop.counter0}}">{% endif %}</td>
-            <td class="updown_td">{% if not forloop.last %}<img src="{{STATIC_URL}}hdabo/img/arrow_down.png" class="down" alt="down" id="{{t.id}}" pos="{{forloop.counter0}}">{% endif %}</td>
-            {% endif %}
-            <td>{{t.id}}</td>
-            <td class="{{t.url_status_text}}">{{t.label}}</td>
-            {% comment %}<td>{{t.original_label}}</td>{% endcomment %}
-            <td class="text_centered">
-	            {% if t.wikipedia_url and t.wikipedia_url != ""  %}
-	            <a href="{{t.wikipedia_url}}" target="_blank"><img src="{{STATIC_URL}}hdabo/img/arrow_right.png" ></a>
-	            {% else %}
-	            <a href="http://fr.wikipedia.org/w/index.php?search={{t.label}}" target="_blank"><img src="{{STATIC_URL}}hdabo/img/wikipedia_search.png" ></a>
-	            {% endif %}</td>
-            <td>facette</td>
-            <td class="text_centered"><input type="checkbox" class="activate_wp_cb" id="{{t.id}}" {% if t.wikipedia_activated %}checked{% endif %} /></td>
-            <td class="text_centered"><img src="{{STATIC_URL}}hdabo/img/red_cross.png" class="remove_wp_link" id="{{t.id}}" /></td>
-            <td>{{t.alias}}</td>
-            <td class="text_centered"><img src="{{STATIC_URL}}hdabo/img/tag_remove.png" class="remove_tag_from_list" id="{{t.id}}" alt="{{t.label}}" /></td></tr>
-        {% endfor %}
-    {% endif %}
-    </table>
-{% endblock %}
+{% block tag_table %}
+	<table id="tag_table"><tr class="nodrop nodrag">
+        <th>#</th>
+        {% if valid != "2" and ordered_tags %}
+        <th><img src="{{STATIC_URL}}hdabo/img/arrow_up_down.png"/></th>
+        {% endif %}
+        <th>id</th>
+        <th>label</th>
+        {% comment %}<th>original_label</th>{% endcomment %}
+        <th class="text_centered">Lien W</th>
+        <th>Facette</th>
+        <th class="large_25 text_centered">Supprimer<br/>le lien W</th>
+        <th>Alias</th>
+        <th class="large_25 text_centered">Retirer le tag de la liste</th></tr>
+    {% if ordered_tags %}
+    	{# ordered_tags is a list of TaggedSheet #}
+        {% for t in ordered_tags %}
+            <tr class="imageline {% cycle 'hdabooddline' 'hdaboevenline' %}" id="{{forloop.counter}}">
+            <td>{{forloop.counter}}</td>
+            {% if valid != "2" %}
+            <td class="updown_td text_centered"><img src="{{STATIC_URL}}hdabo/img/arrow_up_down.png" class="updown" alt="updown" id={{t.tag.id}} pos="{{forloop.counter0}}"></td>
+            {% endif %}
+            <td class="reset_wp_info">{{t.tag.id}}</td>
+            <td class="{{t.tag.url_status_text}} wikipediatag" id="{{t.tag.id}}" >{{t.tag.label}}</td>
+            {% comment %}<td>{{t.tag.original_label}}</td>{% endcomment %}
+            <td class="text_centered">
+	            {% if t.tag.wikipedia_url and t.tag.wikipedia_url != ""  %}
+	            <a href="{{t.tag.wikipedia_url}}" target="_blank"><img src="{{STATIC_URL}}hdabo/img/arrow_right.png" ></a>
+	            {% else %}
+	            <a href="http://fr.wikipedia.org/w/index.php?search={{t.tag.label}}" target="_blank"><img src="{{STATIC_URL}}hdabo/img/wikipedia_search.png" ></a>
+	            {% endif %}</td>
+            <td>{% if t.tag.category %}{{ t.tag.category }}{% endif %}</td>
+            <td class="text_centered"><img src="{{STATIC_URL}}hdabo/img/red_cross.png" class="remove_wp_link" id="{{t.tag.id}}" alt="{{t.tag.label}}" /></td>
+            <td>{% if t.tag.alias %}{{t.tag.alias}}{% endif %}</td>
+            <td class="text_centered"><img src="{{STATIC_URL}}hdabo/img/tag_remove.png" class="remove_tag_from_list" id="{{t.tag.id}}" alt="{{t.tag.label}}" /></td></tr>
+        {% endfor %}
+    {% else %}
+    	{# ds is a DataSheet #}
+        {% for t in ds.tags.all %}
+            <tr class="imageline {% cycle 'hdabooddline' 'hdaboevenline' %}">
+            <td>{{forloop.counter}}</td>
+            {% if valid != "2" and ordered_tags %}
+            <td class="updown_td"><img src="{{STATIC_URL}}hdabo/img/arrow_up_down.png" class="up" alt="up" id="{{t.id}}" pos="{{forloop.counter0}}"></td>
+            {% endif %}
+            <td>{{t.id}}</td>
+            <td class="{{t.url_status_text}}">{{t.label}}</td>
+            {% comment %}<td>{{t.original_label}}</td>{% endcomment %}
+            <td class="text_centered">
+	            {% if t.wikipedia_url and t.wikipedia_url != ""  %}
+	            <a href="{{t.wikipedia_url}}" target="_blank"><img src="{{STATIC_URL}}hdabo/img/arrow_right.png" ></a>
+	            {% else %}
+	            <a href="http://fr.wikipedia.org/w/index.php?search={{t.label}}" target="_blank"><img src="{{STATIC_URL}}hdabo/img/wikipedia_search.png" ></a>
+	            {% endif %}</td>
+            <td>{% if t.category %}{{ t.category }}{% endif %}</td>
+            <td class="text_centered"><img src="{{STATIC_URL}}hdabo/img/red_cross.png" class="remove_wp_link" id="{{t.id}}" /></td>
+            <td>{{t.alias}}</td>
+            <td class="text_centered"><img src="{{STATIC_URL}}hdabo/img/tag_remove.png" class="remove_tag_from_list" id="{{t.id}}" alt="{{t.label}}" /></td></tr>
+        {% endfor %}
+    {% endif %}
+    </table>
+{% endblock %}
--- a/web/hdabo/urls.py	Fri Jun 17 14:17:49 2011 +0200
+++ b/web/hdabo/urls.py	Fri Jun 17 17:14:09 2011 +0200
@@ -34,4 +34,6 @@
     url(r'^validatedatasheet/(?P<ds_id>[\w-]+)$', 'hdabo.views.validate_datasheet'),
     url(r'^validatedatasheet/(?P<ds_id>[\w-]+)/(?P<valid>[\w-]+)/$', 'hdabo.views.validate_datasheet'),
     url(r'^updatetagalias$', 'hdabo.views.update_tag_alias'),
+    url(r'^updatetagcategory$', 'hdabo.views.update_tag_category'),
+    url(r'^getcategories$', 'hdabo.views.get_categories'),
 )
--- a/web/hdabo/views.py	Fri Jun 17 14:17:49 2011 +0200
+++ b/web/hdabo/views.py	Fri Jun 17 17:14:09 2011 +0200
@@ -4,7 +4,7 @@
 from django.contrib.auth.decorators import login_required #@UnusedImport
 from django.core.paginator import Paginator
 from django.db.models import Max
-from django.http import HttpResponseBadRequest
+from django.http import HttpResponse, HttpResponseBadRequest
 from django.shortcuts import render_to_response, redirect
 from django.template import RequestContext
 from haystack.constants import DJANGO_ID
@@ -12,7 +12,7 @@
 from hdabo.management.commands.querywikipedia import process_tag
 from hdabo.wp_utils import (normalize_tag, query_wikipedia_title, 
     get_or_create_tag)
-from models import Organisation, Datasheet, TaggedSheet, Tag
+from models import Datasheet, Organisation, Tag, TagCategory, TaggedSheet
 from wikitools import wiki
 import django.utils.simplejson as json
 
@@ -126,30 +126,31 @@
 #@login_required
 def tag_up_down(request):
     ds_id = request.POST["datasheet_id"]
-    #tag_id = request.POST["tag_id"]
-    # tag_pos indicates the position (from 0) of the tag in the list. NB : it is different from the TagSheet.order in the database.
-    tag_pos = int(request.POST["tag_pos"])
-    # move can be "u" or "d", for up and down
-    move = request.POST["move"]
-    # First we get the datasheet's TaggedSheets
-    ordered_tags = TaggedSheet.objects.filter(datasheet=Datasheet.objects.filter(id=ds_id)[0]).order_by('order')
-    # We get the current TaggedSheet and its's order
-    #ts = ordered_tags.filter(tag=Tag.objects.filter(id=tag_id))[0]
-    ts = ordered_tags[tag_pos]
-    tag_order = ts.order
-    # We get the other TaggedSheet that will be moved
-    if move == "u" :
-        other_ts = ordered_tags[tag_pos - 1]
-    elif move == "d" :
-        other_ts = ordered_tags[tag_pos + 1]
+    # post vars new_order and old_order indicate the position (from 1) of the tag in the list.
+    # NB : it is different from the TagSheet.order in the database.
+    new_order = int(request.POST["new_order"]) - 1
+    old_order = int(request.POST["old_order"]) - 1
+    s = "new_order = " + str(new_order) + ", old_order = " + str(old_order)
+    # First we get the datasheet's TaggedSheets (list to force evaluation)
+    ordered_tags = list(TaggedSheet.objects.filter(datasheet=Datasheet.objects.get(id=ds_id)).order_by('order'))
+    # We change the moved TaggedSheets's order
+    new_ts_order = ordered_tags[new_order].order
+    moved_ts = ordered_tags[old_order]
+    moved_ts.order = new_ts_order
+    moved_ts.save()
+    # We move the TaggedSheets's order
+    if new_order > old_order :
+        # And we decrease the other ones
+        for i in range(old_order+1,new_order+1) :
+            ts = ordered_tags[i]
+            ts.order = ts.order - 1
+            ts.save()
     else :
-        other_ts = None
-    # We switch the orders
-    if other_ts :
-        ts.order = other_ts.order
-        other_ts.order = tag_order
-        ts.save()
-        other_ts.save()
+        # And we increase the other ones
+        for i in range(new_order,old_order) :
+            ts = ordered_tags[i]
+            ts.order = ts.order + 1
+            ts.save()
     
     return get_tag_table(request=request, ds_id=ds_id, valid=0)
 
@@ -215,6 +216,7 @@
     
     if tag.label != tag_label:
 
+
         tag.label = tag_label
         
         site = wiki.Wiki(settings.WIKIPEDIA_API_URL) #@UndefinedVariable
@@ -379,4 +381,26 @@
     else :
         return get_all_tags_table(request=request, num_page=request.POST["num_page"], nb_by_page=request.POST["nb_by_page"])
     
+
+def get_categories(request):
+    
+    resp = "{" + '"":"",' + ", ".join([('"' + c.label + '":"' + c.label + '"') for c in TagCategory.objects.all()]) + "}"
+    
+    return HttpResponse(json.dumps(resp), mimetype="application/json")
+    
+
+#@login_required
+def update_tag_category(request):
+    
+    tag_id = request.POST["id"]
+    cat = request.POST["value"]
+    tag = Tag.objects.get(id=tag_id)
+    if cat and cat != "" :
+        tag.category = TagCategory.objects.get(label=cat)
+    else :
+        tag.category = None
+    tag.save()
+    # This function is available only in all_tags_table context
+    return get_all_tags_table(request=request, num_page=request.POST["num_page"], nb_by_page=request.POST["nb_by_page"])
+    
         
\ No newline at end of file