fix sort of fields vocabulary: should consider option groups stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Mon, 21 Sep 2009 11:41:17 +0200
branchstable
changeset 3334 8d831c02da9a
parent 3332 91cff87c368f
child 3335 3c035436ca65
fix sort of fields vocabulary: should consider option groups
web/formfields.py
web/test/unittest_formfields.py
--- a/web/formfields.py	Fri Sep 18 19:51:45 2009 +0200
+++ b/web/formfields.py	Mon Sep 21 11:41:17 2009 +0200
@@ -22,6 +22,22 @@
     Radio, Select, DateTimePicker)
 
 
+def vocab_sort(vocab):
+    """sort vocabulary, considering option groups"""
+    result = []
+    partresult = []
+    for label, value in vocab:
+        if value is None: # opt group start
+            if partresult:
+                result += sorted(partresult)
+                partresult = []
+            result.append( (label, value) )
+        else:
+            partresult.append( (label, value) )
+    result += sorted(partresult)
+    return result
+
+
 class Field(object):
     """field class is introduced to control what's displayed in forms. It makes
     the link between something to edit and its display in the form. Actual
@@ -190,7 +206,7 @@
         if self.internationalizable:
             vocab = [(form.req._(label), value) for label, value in vocab]
         if self.sort:
-            vocab = sorted(vocab)
+            vocab = vocab_sort(vocab)
         return vocab
 
     def form_init(self, form):
@@ -475,7 +491,7 @@
             relatedvocab = []
         vocab = res + form.form_field_vocabulary(self) + relatedvocab
         if self.sort:
-            vocab = sorted(vocab)
+            vocab = vocab_sort(vocab)
         return vocab
 
     def format_single_value(self, req, value):
--- a/web/test/unittest_formfields.py	Fri Sep 18 19:51:45 2009 +0200
+++ b/web/test/unittest_formfields.py	Mon Sep 21 11:41:17 2009 +0200
@@ -128,5 +128,16 @@
         self.commit()
         self.assertEquals(description_format_field.initial(form), 'text/rest')
 
+
+class UtilsTC(TestCase):
+    def test_vocab_sort(self):
+        self.assertEquals(vocab_sort([('Z', 1), ('A', 2),
+                                      ('Group 1', None), ('Y', 3), ('B', 4),
+                                      ('Group 2', None), ('X', 5), ('C', 6)]),
+                          [('A', 2), ('Z', 1),
+                           ('Group 1', None), ('B', 4), ('Y', 3),
+                           ('Group 2', None), ('C', 6), ('X', 5)]
+                          )
+
 if __name__ == '__main__':
     unittest_main()