[cig-commits] r12063 - cs/portal/trunk/northridge/SeismoWebPortal

leif at geodynamics.org leif at geodynamics.org
Fri May 30 14:17:57 PDT 2008


Author: leif
Date: 2008-05-30 14:17:57 -0700 (Fri, 30 May 2008)
New Revision: 12063

Modified:
   cs/portal/trunk/northridge/SeismoWebPortal/forms.py
Log:
Group parameter sets in the "parameters" pop-up <select> field into
1D, 3D groups using <optgroup>.


Modified: cs/portal/trunk/northridge/SeismoWebPortal/forms.py
===================================================================
--- cs/portal/trunk/northridge/SeismoWebPortal/forms.py	2008-05-30 18:42:57 UTC (rev 12062)
+++ cs/portal/trunk/northridge/SeismoWebPortal/forms.py	2008-05-30 21:17:57 UTC (rev 12063)
@@ -102,21 +102,27 @@
             ('stationList', blank + [(x.id, str(x)) for x in models.StationList.objects.all()]),
             ]
 
-        parametersChoices = list(blank)
-        for ModelClass in [models.Specfem3DGlobeParameters, models.MineosParameters]:
+        parametersChoices = [list(blank)]
+        for groupLabel, ModelClass in [
+            ("3D Parameters (Specfem 3D Globe)", models.Specfem3DGlobeParameters),
+            ("1D Parameters (Mineos)", models.MineosParameters),
+            ]:
             ctype = ContentType.objects.get_for_model(ModelClass)
+            group = []
             for obj in ModelClass.objects.all():
                 value = "%d,%d" % (ctype.id, obj.id)
                 title = str(obj)
-                parametersChoices.append((value, title))
-        self.selectFields.append(
-            ('parameters', parametersChoices)
-            )
+                choice = (value, title)
+                group.append(choice)
+            if group:
+                parametersChoices.append((groupLabel, group))
+        self.parametersChoices = parametersChoices
 
         self.fields = [
             forms.SelectField(fieldName, is_required=True, choices=choices)
             for fieldName, choices in self.selectFields
             ] + [
+            GroupedSelectField('parameters', is_required=True, choices=parametersChoices),
             forms.FloatField('record_length', max_digits=19, decimal_places=10, is_required=True,
                              validator_list=[models.isValidRecordLength]),
             ]
@@ -129,18 +135,17 @@
         if obj:
             for fieldName, choices in self.selectFields:
                 value = getattr(obj, fieldName)
-                if fieldName == 'parameters':
-                    ctype = ContentType.objects.get_for_model(value.__class__)
-                    value = "%d,%d" % (ctype.id, value.id)
-                else:
-                    value = value.id
+                value = value.id
                 data[fieldName] = value
+            data['parameters'] = "%d,%d" % (obj.parametersType.id, obj.parametersId)
             data['record_length'] = obj.record_length
             data['zero_half_duration'] = obj.zero_half_duration
         else:
             for fieldName, choices in self.selectFields:
                 if len(choices) == 2:
                     data[fieldName] = choices[1][0]
+            if len(self.parametersChoices) == 2:
+                data['parameters'] = self.parametersChoices[1][1][0][0]
             data['record_length'] = 20.0
             data['zero_half_duration'] = True
         return data
@@ -527,4 +532,60 @@
 
 
 
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# custom form fields
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+class GroupedSelectField(forms.FormField):
+    def __init__(self, field_name, choices=None, size=1, is_required=False,
+                 validator_list=None, member_name=None):
+        if validator_list is None: validator_list = []
+        if choices is None: choices = []
+        self.field_name = field_name
+        # choices is a list of (value, human-readable key) tuples because order matters
+        self.choices, self.size, self.is_required = choices, size, is_required
+        self.validator_list = [self.isValidChoice] + validator_list
+        if member_name != None:
+            self.member_name = member_name
+
+    def render(self, data):
+        from django.utils.html import escape
+        output = ['<select id="%s" class="v%s%s" name="%s" size="%s">' % \
+            (self.get_id(), self.__class__.__name__,
+             self.is_required and ' required' or '', self.field_name, self.size)]
+        str_data = str(data) # normalize to string
+        for value, display_name in self.choices[0]:
+            selected_html = ''
+            if str(value) == str_data:
+                selected_html = ' selected="selected"'
+            output.append('    <option value="%s"%s>%s</option>' %
+                          (escape(value), selected_html, escape(display_name)))
+        for groupLabel, group in self.choices[1:]:
+            output.append('    <optgroup label="%s">' % groupLabel)
+            for value, display_name in group:
+                selected_html = ''
+                if str(value) == str_data:
+                    selected_html = ' selected="selected"'
+                output.append('    <option value="%s"%s>%s</option>' %
+                              (escape(value), selected_html, escape(display_name)))
+            output.append('    </optgroup>')
+        output.append('  </select>')
+        return '\n'.join(output)
+
+    def isValidChoice(self, data, form):
+        str_data = str(data)
+        str_choices = []
+        for value, display_name in self.choices[0]:
+            if str_data == value:
+                return
+            str_choices.append(value)
+        for groupLabel, group in self.choices[1:]:
+            for value, display_name in group:
+                if str_data == value:
+                    return
+                str_choices.append(value)
+        raise validators.ValidationError, gettext("Select a valid choice; '%(data)s' is not in %(choices)s.") % {'data': str_data, 'choices': str_choices}
+
+
 # end of file



More information about the cig-commits mailing list