--- 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()